dnsapi: Cast-qual warnings fix.
[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., 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 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "shlguid.h"
33
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 #include "mshtml_private.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
40
41 /**********************************************************
42  * IPersistMoniker implementation
43  */
44
45 #define PERSISTMON_THIS(iface) DEFINE_THIS(HTMLDocument, PersistMoniker, iface)
46
47 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid,
48                                                             void **ppvObject)
49 {
50     HTMLDocument *This = PERSISTMON_THIS(iface);
51     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
52 }
53
54 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
55 {
56     HTMLDocument *This = PERSISTMON_THIS(iface);
57     return IHTMLDocument2_AddRef(HTMLDOC(This));
58 }
59
60 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
61 {
62     HTMLDocument *This = PERSISTMON_THIS(iface);
63     return IHTMLDocument2_Release(HTMLDOC(This));
64 }
65
66 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
67 {
68     HTMLDocument *This = PERSISTMON_THIS(iface);
69     return IPersist_GetClassID(PERSIST(This), pClassID);
70 }
71
72 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
73 {
74     HTMLDocument *This = PERSISTMON_THIS(iface);
75     FIXME("(%p)\n", This);
76     return E_NOTIMPL;
77 }
78
79 static nsIInputStream *get_post_data_stream(IBindCtx *bctx)
80 {
81     nsIInputStream *ret = NULL;
82     IBindStatusCallback *callback;
83     IHttpNegotiate *http_negotiate;
84     BINDINFO bindinfo;
85     DWORD bindf = 0;
86     DWORD post_len = 0, headers_len = 0;
87     LPWSTR headers = NULL;
88     WCHAR emptystr[] = {0};
89     char *data;
90     HRESULT hres;
91
92     static WCHAR _BSCB_Holder_[] =
93         {'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
94
95
96     /* FIXME: This should be done in URLMoniker */
97     if(!bctx)
98         return NULL;
99
100     hres = IBindCtx_GetObjectParam(bctx, _BSCB_Holder_, (IUnknown**)&callback);
101     if(FAILED(hres))
102         return NULL;
103
104     hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate,
105                                               (void**)&http_negotiate);
106     if(SUCCEEDED(hres)) {
107         hres = IHttpNegotiate_BeginningTransaction(http_negotiate, emptystr,
108                                                    emptystr, 0, &headers);
109         IHttpNegotiate_Release(http_negotiate);
110
111         if(SUCCEEDED(hres) && headers)
112             headers_len = WideCharToMultiByte(CP_ACP, 0, headers, -1, NULL, 0, NULL, NULL);
113     }
114
115     memset(&bindinfo, 0, sizeof(bindinfo));
116     bindinfo.cbSize = sizeof(bindinfo);
117
118     hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
119
120     if(SUCCEEDED(hres) && bindinfo.dwBindVerb == BINDVERB_POST)
121         post_len = bindinfo.cbStgmedData;
122
123     if(headers_len || post_len) {
124         int len = headers_len ? headers_len-1 : 0;
125
126         static const char content_length[] = "Content-Length: %lu\r\n\r\n";
127
128         data = mshtml_alloc(headers_len+post_len+sizeof(content_length)+8);
129
130         if(headers_len) {
131             WideCharToMultiByte(CP_ACP, 0, headers, -1, data, -1, NULL, NULL);
132             CoTaskMemFree(headers);
133         }
134
135         if(post_len) {
136             sprintf(data+len, content_length, post_len);
137             len = strlen(data);
138
139             memcpy(data+len, bindinfo.stgmedData.u.hGlobal, post_len);
140         }
141
142         TRACE("data = %s\n", debugstr_an(data, len+post_len));
143
144         ret = create_nsstream(data, len+post_len);
145     }
146
147     ReleaseBindInfo(&bindinfo);
148     IBindStatusCallback_Release(callback);
149
150     return ret;
151 }
152
153 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
154         IMoniker *pimkName, LPBC pibc, DWORD grfMode)
155 {
156     HTMLDocument *This = PERSISTMON_THIS(iface);
157     BSCallback *bscallback;
158     LPOLESTR url = NULL;
159     HRESULT hres;
160     nsresult nsres;
161
162     TRACE("(%p)->(%x %p %p %08lx)\n", This, fFullyAvailable, pimkName, pibc, grfMode);
163
164     if(pibc) {
165         IUnknown *unk = NULL;
166
167         /* FIXME:
168          * Use params:
169          * "__PrecreatedObject"
170          * "BIND_CONTEXT_PARAM"
171          * "__HTMLLOADOPTIONS"
172          * "__DWNBINDINFO"
173          * "URL Context"
174          * "CBinding Context"
175          * "_ITransData_Object_"
176          * "_EnumFORMATETC_"
177          */
178
179         IBindCtx_GetObjectParam(pibc, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, &unk);
180         if(unk) {
181             IOleClientSite *client = NULL;
182
183             hres = IUnknown_QueryInterface(unk, &IID_IOleClientSite, (void**)&client);
184             if(SUCCEEDED(hres)) {
185                 TRACE("Got client site %p\n", client);
186                 IOleObject_SetClientSite(OLEOBJ(This), client);
187                 IOleClientSite_Release(client);
188             }
189
190             IUnknown_Release(unk);
191         }
192     }
193
194     call_property_onchanged(This->cp_propnotif, DISPID_READYSTATE);
195
196     HTMLDocument_LockContainer(This, TRUE);
197     
198     hres = IMoniker_GetDisplayName(pimkName, pibc, NULL, &url);
199     if(FAILED(hres)) {
200         WARN("GetDiaplayName failed: %08lx\n", hres);
201         return hres;
202     }
203
204     TRACE("got url: %s\n", debugstr_w(url));
205
206     if(This->client) {
207         IOleCommandTarget *cmdtrg = NULL;
208
209         hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
210                 (void**)&cmdtrg);
211         if(SUCCEEDED(hres)) {
212             VARIANT var;
213
214             V_VT(&var) = VT_I4;
215             V_I4(&var) = 0;
216             IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL);
217         }
218     }
219
220     bscallback = create_bscallback(This, pimkName);
221
222     if(This->nscontainer) {
223         nsIInputStream *post_data_stream = get_post_data_stream(pibc);
224
225         This->nscontainer->bscallback = bscallback;
226         nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url,
227                 LOAD_FLAGS_NONE, NULL, post_data_stream, NULL);
228         This->nscontainer->bscallback = NULL;
229
230         if(post_data_stream)
231             nsIInputStream_Release(post_data_stream);
232
233         if(!bscallback->nschannel)
234             ERR("bscallback->nschannel == NULL\n");
235
236         if(NS_SUCCEEDED(nsres)) {
237             /* FIXME: don't return here (URL Moniker needs to be good enough) */
238
239             IBindStatusCallback_Release(STATUSCLB(bscallback));
240             CoTaskMemFree(url);
241             return S_OK;
242         }else if(nsres != WINE_NS_LOAD_FROM_MONIKER) {
243             WARN("LoadURI failed: %08lx\n", nsres);
244         }
245     }
246
247     /* FIXME: Use grfMode */
248
249     if(fFullyAvailable)
250         FIXME("not supported fFullyAvailable\n");
251     if(pibc)
252         FIXME("not supported pibc\n");
253
254     hres = start_binding(bscallback);
255
256     IBindStatusCallback_Release(STATUSCLB(bscallback));
257     CoTaskMemFree(url);
258
259     return hres;
260 }
261
262 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName,
263         LPBC pbc, BOOL fRemember)
264 {
265     HTMLDocument *This = PERSISTMON_THIS(iface);
266     FIXME("(%p)->(%p %p %x)\n", This, pimkName, pbc, fRemember);
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
271 {
272     HTMLDocument *This = PERSISTMON_THIS(iface);
273     FIXME("(%p)->(%p %p)\n", This, pimkName, pibc);
274     return E_NOTIMPL;
275 }
276
277 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **ppimkName)
278 {
279     HTMLDocument *This = PERSISTMON_THIS(iface);
280     FIXME("(%p)->(%p)\n", This, ppimkName);
281     return E_NOTIMPL;
282 }
283
284 static const IPersistMonikerVtbl PersistMonikerVtbl = {
285     PersistMoniker_QueryInterface,
286     PersistMoniker_AddRef,
287     PersistMoniker_Release,
288     PersistMoniker_GetClassID,
289     PersistMoniker_IsDirty,
290     PersistMoniker_Load,
291     PersistMoniker_Save,
292     PersistMoniker_SaveCompleted,
293     PersistMoniker_GetCurMoniker
294 };
295
296 /**********************************************************
297  * IMonikerProp implementation
298  */
299
300 #define MONPROP_THIS(iface) DEFINE_THIS(HTMLDocument, MonikerProp, iface)
301
302 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppvObject)
303 {
304     HTMLDocument *This = MONPROP_THIS(iface);
305     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
306 }
307
308 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
309 {
310     HTMLDocument *This = MONPROP_THIS(iface);
311     return IHTMLDocument2_AddRef(HTMLDOC(This));
312 }
313
314 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
315 {
316     HTMLDocument *This = MONPROP_THIS(iface);
317     return IHTMLDocument_Release(HTMLDOC(This));
318 }
319
320 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
321 {
322     HTMLDocument *This = MONPROP_THIS(iface);
323     FIXME("(%p)->(%d %s)\n", This, mkp, debugstr_w(val));
324     return E_NOTIMPL;
325 }
326
327 static const IMonikerPropVtbl MonikerPropVtbl = {
328     MonikerProp_QueryInterface,
329     MonikerProp_AddRef,
330     MonikerProp_Release,
331     MonikerProp_PutProperty
332 };
333
334 /**********************************************************
335  * IPersistFile implementation
336  */
337
338 #define PERSISTFILE_THIS(iface) DEFINE_THIS(HTMLDocument, PersistFile, iface)
339
340 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *iface, REFIID riid, void **ppvObject)
341 {
342     HTMLDocument *This = PERSISTFILE_THIS(iface);
343     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
344 }
345
346 static ULONG WINAPI PersistFile_AddRef(IPersistFile *iface)
347 {
348     HTMLDocument *This = PERSISTFILE_THIS(iface);
349     return IHTMLDocument2_AddRef(HTMLDOC(This));
350 }
351
352 static ULONG WINAPI PersistFile_Release(IPersistFile *iface)
353 {
354     HTMLDocument *This = PERSISTFILE_THIS(iface);
355     return IHTMLDocument2_Release(HTMLDOC(This));
356 }
357
358 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *iface, CLSID *pClassID)
359 {
360     HTMLDocument *This = PERSISTFILE_THIS(iface);
361
362     TRACE("(%p)->(%p)\n", This, pClassID);
363
364     if(!pClassID)
365         return E_INVALIDARG;
366
367     memcpy(pClassID, &CLSID_HTMLDocument, sizeof(CLSID));
368     return S_OK;
369 }
370
371 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *iface)
372 {
373     HTMLDocument *This = PERSISTFILE_THIS(iface);
374     FIXME("(%p)\n", This);
375     return E_NOTIMPL;
376 }
377
378 static HRESULT WINAPI PersistFile_Load(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
379 {
380     HTMLDocument *This = PERSISTFILE_THIS(iface);
381     FIXME("(%p)->(%s %08lx)\n", This, debugstr_w(pszFileName), dwMode);
382     return E_NOTIMPL;
383 }
384
385 static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
386 {
387     HTMLDocument *This = PERSISTFILE_THIS(iface);
388     FIXME("(%p)->(%s %x)\n", This, debugstr_w(pszFileName), fRemember);
389     return E_NOTIMPL;
390 }
391
392 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
393 {
394     HTMLDocument *This = PERSISTFILE_THIS(iface);
395     FIXME("(%p)->(%s)\n", This, debugstr_w(pszFileName));
396     return E_NOTIMPL;
397 }
398
399 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *pszFileName)
400 {
401     HTMLDocument *This = PERSISTFILE_THIS(iface);
402     FIXME("(%p)->(%p)\n", This, pszFileName);
403     return E_NOTIMPL;
404 }
405
406 static const IPersistFileVtbl PersistFileVtbl = {
407     PersistFile_QueryInterface,
408     PersistFile_AddRef,
409     PersistFile_Release,
410     PersistFile_GetClassID,
411     PersistFile_IsDirty,
412     PersistFile_Load,
413     PersistFile_Save,
414     PersistFile_SaveCompleted,
415     PersistFile_GetCurFile
416 };
417
418 #define PERSTRINIT_THIS(iface) DEFINE_THIS(HTMLDocument, PersistStreamInit, iface);
419
420 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface,
421                                                        REFIID riid, void **ppv)
422 {
423     HTMLDocument *This = PERSTRINIT_THIS(iface);
424     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
425 }
426
427 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
428 {
429     HTMLDocument *This = PERSTRINIT_THIS(iface);
430     return IHTMLDocument2_AddRef(HTMLDOC(This));
431 }
432
433 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
434 {
435     HTMLDocument *This = PERSTRINIT_THIS(iface);
436     return IHTMLDocument2_AddRef(HTMLDOC(This));
437 }
438
439 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
440 {
441     HTMLDocument *This = PERSTRINIT_THIS(iface);
442     return IPersist_GetClassID(PERSIST(This), pClassID);
443 }
444
445 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
446 {
447     HTMLDocument *This = PERSTRINIT_THIS(iface);
448     FIXME("(%p)\n", This);
449     return E_NOTIMPL;
450 }
451
452 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStm)
453 {
454     HTMLDocument *This = PERSTRINIT_THIS(iface);
455     FIXME("(%p)->(%p)\n", This, pStm);
456     return E_NOTIMPL;
457 }
458
459 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm,
460                                              BOOL fClearDirty)
461 {
462     HTMLDocument *This = PERSTRINIT_THIS(iface);
463     FIXME("(%p)->(%p %x)\n", This, pStm, fClearDirty);
464     return E_NOTIMPL;
465 }
466
467 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface,
468                                                    ULARGE_INTEGER *pcbSize)
469 {
470     HTMLDocument *This = PERSTRINIT_THIS(iface);
471     FIXME("(%p)->(%p)\n", This, pcbSize);
472     return E_NOTIMPL;
473 }
474
475 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
476 {
477     HTMLDocument *This = PERSTRINIT_THIS(iface);
478     FIXME("(%p)\n", This);
479     return E_NOTIMPL;
480 }
481
482 #undef PERSTRINIT_THIS
483
484 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
485     PersistStreamInit_QueryInterface,
486     PersistStreamInit_AddRef,
487     PersistStreamInit_Release,
488     PersistStreamInit_GetClassID,
489     PersistStreamInit_IsDirty,
490     PersistStreamInit_Load,
491     PersistStreamInit_Save,
492     PersistStreamInit_GetSizeMax,
493     PersistStreamInit_InitNew
494 };
495
496 void HTMLDocument_Persist_Init(HTMLDocument *This)
497 {
498     This->lpPersistMonikerVtbl = &PersistMonikerVtbl;
499     This->lpPersistFileVtbl = &PersistFileVtbl;
500     This->lpMonikerPropVtbl = &MonikerPropVtbl;
501     This->lpPersistStreamInitVtbl = &PersistStreamInitVtbl;
502 }