urlmon: Fix the case of the BINDINFO.cbstgmedData field. Fixes the htmldoc test compi...
[wine/multimedia.git] / dlls / mshtml / persist.c
blobd9eb099160e7da58729315ba326d5791d918cefb
1 /*
2 * Copyright 2005 Jacek Caban
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "shlguid.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
37 #include "mshtml_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41 /**********************************************************
42 * IPersistMoniker implementation
45 #define PERSISTMON_THIS(iface) DEFINE_THIS(HTMLDocument, PersistMoniker, iface)
47 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid,
48 void **ppvObject)
50 HTMLDocument *This = PERSISTMON_THIS(iface);
51 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
54 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
56 HTMLDocument *This = PERSISTMON_THIS(iface);
57 return IHTMLDocument2_AddRef(HTMLDOC(This));
60 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
62 HTMLDocument *This = PERSISTMON_THIS(iface);
63 return IHTMLDocument2_Release(HTMLDOC(This));
66 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
68 HTMLDocument *This = PERSISTMON_THIS(iface);
69 return IPersist_GetClassID(PERSIST(This), pClassID);
72 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
74 HTMLDocument *This = PERSISTMON_THIS(iface);
75 FIXME("(%p)\n", This);
76 return E_NOTIMPL;
79 static nsIInputStream *get_post_data_stream(IBindCtx *bctx)
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;
92 static WCHAR _BSCB_Holder_[] =
93 {'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
96 /* FIXME: This should be done in URLMoniker */
97 if(!bctx)
98 return NULL;
100 hres = IBindCtx_GetObjectParam(bctx, _BSCB_Holder_, (IUnknown**)&callback);
101 if(FAILED(hres))
102 return NULL;
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);
111 if(SUCCEEDED(hres) && headers)
112 headers_len = WideCharToMultiByte(CP_ACP, 0, headers, -1, NULL, 0, NULL, NULL);
115 memset(&bindinfo, 0, sizeof(bindinfo));
116 bindinfo.cbSize = sizeof(bindinfo);
118 hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
120 if(SUCCEEDED(hres) && bindinfo.dwBindVerb == BINDVERB_POST)
121 post_len = bindinfo.cbstgmedData;
123 if(headers_len || post_len) {
124 int len = headers_len ? headers_len-1 : 0;
126 static const char content_length[] = "Content-Length: %lu\r\n\r\n";
128 data = mshtml_alloc(headers_len+post_len+sizeof(content_length)+8);
130 if(headers_len) {
131 WideCharToMultiByte(CP_ACP, 0, headers, -1, data, -1, NULL, NULL);
132 CoTaskMemFree(headers);
135 if(post_len) {
136 sprintf(data+len, content_length, post_len);
137 len = strlen(data);
139 memcpy(data+len, bindinfo.stgmedData.u.hGlobal, post_len);
142 TRACE("data = %s\n", debugstr_an(data, len+post_len));
144 ret = create_nsstream(data, len+post_len);
147 ReleaseBindInfo(&bindinfo);
148 IBindStatusCallback_Release(callback);
150 return ret;
153 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
154 IMoniker *pimkName, LPBC pibc, DWORD grfMode)
156 HTMLDocument *This = PERSISTMON_THIS(iface);
157 BSCallback *bscallback;
158 LPOLESTR url = NULL;
159 task_t *task;
160 HRESULT hres;
161 nsresult nsres;
163 TRACE("(%p)->(%x %p %p %08lx)\n", This, fFullyAvailable, pimkName, pibc, grfMode);
165 if(pibc) {
166 IUnknown *unk = NULL;
168 /* FIXME:
169 * Use params:
170 * "__PrecreatedObject"
171 * "BIND_CONTEXT_PARAM"
172 * "__HTMLLOADOPTIONS"
173 * "__DWNBINDINFO"
174 * "URL Context"
175 * "CBinding Context"
176 * "_ITransData_Object_"
177 * "_EnumFORMATETC_"
180 IBindCtx_GetObjectParam(pibc, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, &unk);
181 if(unk) {
182 IOleClientSite *client = NULL;
184 hres = IUnknown_QueryInterface(unk, &IID_IOleClientSite, (void**)&client);
185 if(SUCCEEDED(hres)) {
186 TRACE("Got client site %p\n", client);
187 IOleObject_SetClientSite(OLEOBJ(This), client);
188 IOleClientSite_Release(client);
191 IUnknown_Release(unk);
195 This->readystate = READYSTATE_LOADING;
196 call_property_onchanged(This->cp_propnotif, DISPID_READYSTATE);
198 HTMLDocument_LockContainer(This, TRUE);
200 hres = IMoniker_GetDisplayName(pimkName, pibc, NULL, &url);
201 if(FAILED(hres)) {
202 WARN("GetDiaplayName failed: %08lx\n", hres);
203 return hres;
206 TRACE("got url: %s\n", debugstr_w(url));
208 if(This->client) {
209 IOleCommandTarget *cmdtrg = NULL;
211 hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
212 (void**)&cmdtrg);
213 if(SUCCEEDED(hres)) {
214 VARIANT var;
216 V_VT(&var) = VT_I4;
217 V_I4(&var) = 0;
218 IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL);
222 bscallback = create_bscallback(pimkName);
224 task = mshtml_alloc(sizeof(task_t));
226 task->doc = This;
227 task->task_id = TASK_SETDOWNLOADSTATE;
228 task->next = NULL;
230 push_task(task);
232 if(This->nscontainer) {
233 nsIInputStream *post_data_stream = get_post_data_stream(pibc);
235 This->nscontainer->bscallback = bscallback;
236 nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url,
237 LOAD_FLAGS_NONE, NULL, post_data_stream, NULL);
238 This->nscontainer->bscallback = NULL;
240 if(post_data_stream)
241 nsIInputStream_Release(post_data_stream);
243 if(!bscallback->nschannel)
244 ERR("bscallback->nschannel == NULL\n");
246 if(NS_SUCCEEDED(nsres)) {
247 /* FIXME: don't return here (URL Moniker needs to be good enough) */
249 IBindStatusCallback_Release(STATUSCLB(bscallback));
250 CoTaskMemFree(url);
251 return S_OK;
252 }else if(nsres != WINE_NS_LOAD_FROM_MONIKER) {
253 WARN("LoadURI failed: %08lx\n", nsres);
257 set_document_bscallback(This, bscallback);
258 hres = start_binding(bscallback);
260 IBindStatusCallback_Release(STATUSCLB(bscallback));
261 CoTaskMemFree(url);
263 return hres;
266 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName,
267 LPBC pbc, BOOL fRemember)
269 HTMLDocument *This = PERSISTMON_THIS(iface);
270 FIXME("(%p)->(%p %p %x)\n", This, pimkName, pbc, fRemember);
271 return E_NOTIMPL;
274 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
276 HTMLDocument *This = PERSISTMON_THIS(iface);
277 FIXME("(%p)->(%p %p)\n", This, pimkName, pibc);
278 return E_NOTIMPL;
281 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **ppimkName)
283 HTMLDocument *This = PERSISTMON_THIS(iface);
284 FIXME("(%p)->(%p)\n", This, ppimkName);
285 return E_NOTIMPL;
288 static const IPersistMonikerVtbl PersistMonikerVtbl = {
289 PersistMoniker_QueryInterface,
290 PersistMoniker_AddRef,
291 PersistMoniker_Release,
292 PersistMoniker_GetClassID,
293 PersistMoniker_IsDirty,
294 PersistMoniker_Load,
295 PersistMoniker_Save,
296 PersistMoniker_SaveCompleted,
297 PersistMoniker_GetCurMoniker
300 /**********************************************************
301 * IMonikerProp implementation
304 #define MONPROP_THIS(iface) DEFINE_THIS(HTMLDocument, MonikerProp, iface)
306 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppvObject)
308 HTMLDocument *This = MONPROP_THIS(iface);
309 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
312 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
314 HTMLDocument *This = MONPROP_THIS(iface);
315 return IHTMLDocument2_AddRef(HTMLDOC(This));
318 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
320 HTMLDocument *This = MONPROP_THIS(iface);
321 return IHTMLDocument_Release(HTMLDOC(This));
324 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
326 HTMLDocument *This = MONPROP_THIS(iface);
327 FIXME("(%p)->(%d %s)\n", This, mkp, debugstr_w(val));
328 return E_NOTIMPL;
331 static const IMonikerPropVtbl MonikerPropVtbl = {
332 MonikerProp_QueryInterface,
333 MonikerProp_AddRef,
334 MonikerProp_Release,
335 MonikerProp_PutProperty
338 /**********************************************************
339 * IPersistFile implementation
342 #define PERSISTFILE_THIS(iface) DEFINE_THIS(HTMLDocument, PersistFile, iface)
344 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *iface, REFIID riid, void **ppvObject)
346 HTMLDocument *This = PERSISTFILE_THIS(iface);
347 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
350 static ULONG WINAPI PersistFile_AddRef(IPersistFile *iface)
352 HTMLDocument *This = PERSISTFILE_THIS(iface);
353 return IHTMLDocument2_AddRef(HTMLDOC(This));
356 static ULONG WINAPI PersistFile_Release(IPersistFile *iface)
358 HTMLDocument *This = PERSISTFILE_THIS(iface);
359 return IHTMLDocument2_Release(HTMLDOC(This));
362 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *iface, CLSID *pClassID)
364 HTMLDocument *This = PERSISTFILE_THIS(iface);
366 TRACE("(%p)->(%p)\n", This, pClassID);
368 if(!pClassID)
369 return E_INVALIDARG;
371 memcpy(pClassID, &CLSID_HTMLDocument, sizeof(CLSID));
372 return S_OK;
375 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *iface)
377 HTMLDocument *This = PERSISTFILE_THIS(iface);
378 FIXME("(%p)\n", This);
379 return E_NOTIMPL;
382 static HRESULT WINAPI PersistFile_Load(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
384 HTMLDocument *This = PERSISTFILE_THIS(iface);
385 FIXME("(%p)->(%s %08lx)\n", This, debugstr_w(pszFileName), dwMode);
386 return E_NOTIMPL;
389 static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
391 HTMLDocument *This = PERSISTFILE_THIS(iface);
392 FIXME("(%p)->(%s %x)\n", This, debugstr_w(pszFileName), fRemember);
393 return E_NOTIMPL;
396 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
398 HTMLDocument *This = PERSISTFILE_THIS(iface);
399 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFileName));
400 return E_NOTIMPL;
403 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *pszFileName)
405 HTMLDocument *This = PERSISTFILE_THIS(iface);
406 FIXME("(%p)->(%p)\n", This, pszFileName);
407 return E_NOTIMPL;
410 static const IPersistFileVtbl PersistFileVtbl = {
411 PersistFile_QueryInterface,
412 PersistFile_AddRef,
413 PersistFile_Release,
414 PersistFile_GetClassID,
415 PersistFile_IsDirty,
416 PersistFile_Load,
417 PersistFile_Save,
418 PersistFile_SaveCompleted,
419 PersistFile_GetCurFile
422 #define PERSTRINIT_THIS(iface) DEFINE_THIS(HTMLDocument, PersistStreamInit, iface)
424 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface,
425 REFIID riid, void **ppv)
427 HTMLDocument *This = PERSTRINIT_THIS(iface);
428 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
431 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
433 HTMLDocument *This = PERSTRINIT_THIS(iface);
434 return IHTMLDocument2_AddRef(HTMLDOC(This));
437 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
439 HTMLDocument *This = PERSTRINIT_THIS(iface);
440 return IHTMLDocument2_AddRef(HTMLDOC(This));
443 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
445 HTMLDocument *This = PERSTRINIT_THIS(iface);
446 return IPersist_GetClassID(PERSIST(This), pClassID);
449 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
451 HTMLDocument *This = PERSTRINIT_THIS(iface);
452 FIXME("(%p)\n", This);
453 return E_NOTIMPL;
456 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStm)
458 HTMLDocument *This = PERSTRINIT_THIS(iface);
459 FIXME("(%p)->(%p)\n", This, pStm);
460 return E_NOTIMPL;
463 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm,
464 BOOL fClearDirty)
466 HTMLDocument *This = PERSTRINIT_THIS(iface);
467 FIXME("(%p)->(%p %x)\n", This, pStm, fClearDirty);
468 return E_NOTIMPL;
471 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface,
472 ULARGE_INTEGER *pcbSize)
474 HTMLDocument *This = PERSTRINIT_THIS(iface);
475 FIXME("(%p)->(%p)\n", This, pcbSize);
476 return E_NOTIMPL;
479 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
481 HTMLDocument *This = PERSTRINIT_THIS(iface);
482 FIXME("(%p)\n", This);
483 return E_NOTIMPL;
486 #undef PERSTRINIT_THIS
488 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
489 PersistStreamInit_QueryInterface,
490 PersistStreamInit_AddRef,
491 PersistStreamInit_Release,
492 PersistStreamInit_GetClassID,
493 PersistStreamInit_IsDirty,
494 PersistStreamInit_Load,
495 PersistStreamInit_Save,
496 PersistStreamInit_GetSizeMax,
497 PersistStreamInit_InitNew
500 void HTMLDocument_Persist_Init(HTMLDocument *This)
502 This->lpPersistMonikerVtbl = &PersistMonikerVtbl;
503 This->lpPersistFileVtbl = &PersistFileVtbl;
504 This->lpMonikerPropVtbl = &MonikerPropVtbl;
505 This->lpPersistStreamInitVtbl = &PersistStreamInitVtbl;
507 This->bscallback = NULL;