Module: wine Branch: refs/heads/master Commit: 4b511edf8d5ab2a0ab0fe08d762ec2ded445bcd0 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=4b511edf8d5ab2a0ab0fe08d...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Feb 15 11:52:33 2006 +0100
mshtml: Added hack to allow pass post data to IPersistMoniker::Load.
---
dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/nsembed.c | 27 ++++++++++++ dlls/mshtml/nsiface.idl | 11 +++++ dlls/mshtml/persist.c | 94 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 52968bc..2bc9560 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -158,6 +158,8 @@ PRUint32 nsACString_GetData(const nsACSt void nsACString_SetData(nsACString*,const char*); void nsACString_Destroy(nsACString*);
+nsIInputStream *create_nsstream(const char*,PRInt32); + IHlink *Hlink_Create(void);
DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 809c273..dbe0d56 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1" #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1" #define NS_PROFILE_CONTRACTID "@mozilla.org/profile/manager;1" +#define NS_STRINGSTREAM_CONTRACTID "@mozilla.org/io/string-input-stream;1"
#define APPSTARTUP_TOPIC "app-startup"
@@ -388,6 +389,32 @@ void nsACString_Destroy(nsACString *str) HeapFree(GetProcessHeap(), 0, str); }
+nsIInputStream *create_nsstream(const char *data, PRInt32 data_len) +{ + nsIStringInputStream *ret; + nsresult nsres; + + if(!pCompMgr) + return NULL; + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, + NS_STRINGSTREAM_CONTRACTID, NULL, &IID_nsIStringInputStream, + (void**)&ret); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIStringInputStream\n"); + return NULL; + } + + nsres = nsIStringInputStream_SetData(ret, data, data_len); + if(NS_FAILED(nsres)) { + ERR("AdoptData failed: %08lx\n", nsres); + nsIStringInputStream_Release(ret); + return NULL; + } + + return (nsIInputStream*)ret; +} + void close_gecko() { TRACE("()\n"); diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 382e7b9..a54df54 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -145,6 +145,17 @@ interface nsIInputStream : nsISupports
[ object, + uuid(450cd2d4-f0fd-424d-b365-b1251f80fd53) +] +interface nsIStringInputStream : nsIInputStream +{ + nsresult SetData(const char *data, PRInt32 dataLen); + nsresult AdoptData(char *data, PRInt32 dataLen); + nsresult ShareData(const char *data, PRInt32 dataLen); +} + +[ + object, uuid(07a22cc0-0ce5-11d3-9331-00104ba0fd40) ] interface nsIURI : nsISupports diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index ae883a0..7649ee6 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -32,6 +32,7 @@ #include "shlguid.h"
#include "wine/debug.h" +#include "wine/unicode.h"
#include "mshtml_private.h"
@@ -221,6 +222,8 @@ static HRESULT WINAPI BindStatusCallback return E_NOTIMPL; }
+#undef STATUSCLB_THIS + static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { BindStatusCallback_QueryInterface, BindStatusCallback_AddRef, @@ -238,12 +241,14 @@ static const IBindStatusCallbackVtbl Bin static BindStatusCallback *BindStatusCallback_Create(HTMLDocument *doc, LPOLESTR url) { BindStatusCallback *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(BindStatusCallback)); + ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; ret->ref = 0; ret->url = url; ret->doc = doc; ret->stream = NULL; IHTMLDocument2_AddRef(HTMLDOC(doc)); + return ret; }
@@ -285,6 +290,80 @@ static HRESULT WINAPI PersistMoniker_IsD return E_NOTIMPL; }
+static nsIInputStream *get_post_data_stream(IBindCtx *bctx) +{ + nsIInputStream *ret = NULL; + IBindStatusCallback *callback; + IHttpNegotiate *http_negotiate; + BINDINFO bindinfo; + DWORD bindf = 0; + DWORD post_len = 0, headers_len = 0; + LPWSTR headers = NULL; + WCHAR emptystr[] = {0}; + char *data; + HRESULT hres; + + static WCHAR _BSCB_Holder_[] = + {'_','B','S','C','B','_','H','o','l','d','e','r','_',0}; + + + /* FIXME: This should be done in URLMoniker */ + if(!bctx) + return NULL; + + hres = IBindCtx_GetObjectParam(bctx, _BSCB_Holder_, (IUnknown**)&callback); + if(FAILED(hres)) + return NULL; + + hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate, + (void**)&http_negotiate); + if(SUCCEEDED(hres)) { + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, emptystr, + emptystr, 0, &headers); + IHttpNegotiate_Release(http_negotiate); + + if(SUCCEEDED(hres) && headers) + headers_len = WideCharToMultiByte(CP_ACP, 0, headers, -1, NULL, 0, NULL, NULL); + } + + memset(&bindinfo, 0, sizeof(bindinfo)); + bindinfo.cbSize = sizeof(bindinfo); + + hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo); + + if(SUCCEEDED(hres) && bindinfo.dwBindVerb == BINDVERB_POST) + post_len = bindinfo.cbStgmedData-1; + + if(headers_len || post_len) { + int len = headers_len; + + static const char content_length[] = "Content-Length: %lu\r\n\r\n"; + + data = HeapAlloc(GetProcessHeap(), 0, headers_len+post_len+sizeof(content_length)+8); + + if(headers_len) { + WideCharToMultiByte(CP_ACP, 0, headers, -1, data, -1, NULL, NULL); + CoTaskMemFree(headers); + } + + if(post_len) { + sprintf(data+headers_len-1, content_length, post_len); + len = strlen(data); + + memcpy(data+len, bindinfo.stgmedData.u.hGlobal, post_len); + } + + TRACE("data = %s\n", debugstr_an(data, len+post_len)); + + ret = create_nsstream(data, strlen(data)); + } + + ReleaseBindInfo(&bindinfo); + IBindStatusCallback_Release(callback); + + return ret; +} + static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable, IMoniker *pimkName, LPBC pibc, DWORD grfMode) { @@ -358,15 +437,23 @@ static HRESULT WINAPI PersistMoniker_Loa * It uses Gecko's LoadURI instead of IMoniker's BindToStorage. Should we improve * it (to do so we'd have to use not frozen interfaces)? */ + + nsIInputStream *post_data_stream = get_post_data_stream(pibc);; + This->nscontainer->load_call = TRUE; nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url, - LOAD_FLAGS_NONE, NULL, NULL, NULL); + LOAD_FLAGS_NONE, NULL, post_data_stream, NULL); This->nscontainer->load_call = FALSE;
- if(NS_SUCCEEDED(nsres)) + if(post_data_stream) + nsIInputStream_Release(post_data_stream); + + if(NS_SUCCEEDED(nsres)) { + CoTaskMemFree(url); return S_OK; - else + }else { WARN("LoadURI failed: %08lx\n", nsres); + } }
/* FIXME: Use grfMode */ @@ -378,6 +465,7 @@ static HRESULT WINAPI PersistMoniker_Loa IBinding_Abort(This->status_callback->binding);
callback = This->status_callback = BindStatusCallback_Create(This, url); + CoTaskMemFree(url);
if(pibc) { pbind = pibc;