Jacek Caban : mshtml: Added hack to allow pass post data to
IPersistMoniker ::Load.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Feb 15 07:01:12 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 4b511edf8d5ab2a0ab0fe08d762ec2ded445bcd0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=4b511edf8d5ab2a0ab0fe08d762ec2ded445bcd0
Author: Jacek Caban <jacek at 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;
More information about the wine-cvs
mailing list