Module: wine Branch: master Commit: 58bce9422e769706f4d6bd99b1d6368a630a2fb6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=58bce9422e769706f4d6bd99b1...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Oct 6 04:44:00 2010 +0400
msxml3: Implement ready state change callback.
---
dlls/msxml3/httprequest.c | 24 ++++++- dlls/msxml3/tests/domdoc.c | 139 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 158 insertions(+), 5 deletions(-)
diff --git a/dlls/msxml3/httprequest.c b/dlls/msxml3/httprequest.c index f1a93f6..7deae26 100644 --- a/dlls/msxml3/httprequest.c +++ b/dlls/msxml3/httprequest.c @@ -60,6 +60,7 @@ typedef struct LONG ref;
READYSTATE state; + IDispatch *sink;
/* request */ BINDVERB verb; @@ -415,10 +416,17 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback * return hr; }
-/* TODO: process OnChange callback */ static void httprequest_setreadystate(httprequest *This, READYSTATE state) { This->state = state; + + if (This->sink) + { + DISPPARAMS params; + + memset(¶ms, 0, sizeof(params)); + IDispatch_Invoke(This->sink, 0, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, 0, 0, 0); + } }
static HRESULT WINAPI httprequest_QueryInterface(IXMLHTTPRequest *iface, REFIID riid, void **ppvObject) @@ -477,6 +485,8 @@ static ULONG WINAPI httprequest_Release(IXMLHTTPRequest *iface) /* detach callback object */ BindStatusCallback_Detach(This->bsc);
+ if (This->sink) IDispatch_Release(This->sink); + heap_free( This ); }
@@ -768,13 +778,16 @@ static HRESULT WINAPI httprequest_get_readyState(IXMLHTTPRequest *iface, LONG *s return S_OK; }
-static HRESULT WINAPI httprequest_put_onreadystatechange(IXMLHTTPRequest *iface, IDispatch *pReadyStateSink) +static HRESULT WINAPI httprequest_put_onreadystatechange(IXMLHTTPRequest *iface, IDispatch *sink) { httprequest *This = impl_from_IXMLHTTPRequest( iface );
- FIXME("stub %p %p\n", This, pReadyStateSink); + TRACE("(%p)->(%p)\n", This, sink);
- return E_NOTIMPL; + if (This->sink) IDispatch_Release(This->sink); + if ((This->sink = sink)) IDispatch_AddRef(This->sink); + + return S_OK; }
static const struct IXMLHTTPRequestVtbl dimimpl_vtbl = @@ -819,7 +832,10 @@ HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, void **ppObj) req->async = FALSE; req->verb = -1; req->url = req->user = req->password = NULL; + req->state = READYSTATE_UNINITIALIZED; + req->sink = NULL; + req->bsc = NULL; req->status = 0; req->reqheader_size = 0; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 2c261fe..bcc9842 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -40,6 +40,117 @@ DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f,0x20, 0x00,0x80,0x5f,0x2c,0xd0,0x64); DEFINE_GUID(CLSID_DOMDocument60, 0x88d96a05, 0xf192, 0x11d4, 0xa6,0x5f, 0x00,0x40,0x96,0x32,0x51,0xe5);
+static int g_unexpectedcall, g_expectedcall; + +typedef struct +{ + const struct IDispatchVtbl *lpVtbl; + LONG ref; +} dispevent; + +static inline dispevent *impl_from_IDispatch( IDispatch *iface ) +{ + return (dispevent *)((char*)iface - FIELD_OFFSET(dispevent, lpVtbl)); +} + +static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject) +{ + *ppvObject = NULL; + + if ( IsEqualGUID( riid, &IID_IDispatch) || + IsEqualGUID( riid, &IID_IUnknown) ) + { + *ppvObject = iface; + } + else + return E_NOINTERFACE; + + IDispatch_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI dispevent_AddRef(IDispatch *iface) +{ + dispevent *This = impl_from_IDispatch( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI dispevent_Release(IDispatch *iface) +{ + dispevent *This = impl_from_IDispatch( iface ); + ULONG ref = InterlockedDecrement( &This->ref ); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) +{ + g_unexpectedcall++; + *pctinfo = 0; + return S_OK; +} + +static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + g_unexpectedcall++; + return S_OK; +} + +static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + g_unexpectedcall++; + return S_OK; +} + +static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid, + LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, + EXCEPINFO *excepInfo, UINT *argErr) +{ + ok(member == 0, "expected 0 member, got %d\n", member); + ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid); + ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags); + + ok(params->cArgs == 0, "got %d\n", params->cArgs); + ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs); + ok(params->rgvarg == NULL, "got %p\n", params->rgvarg); + ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs); + + ok(result == NULL, "got %p\n", result); + ok(excepInfo == NULL, "got %p\n", excepInfo); + ok(argErr == NULL, "got %p\n", argErr); + + g_expectedcall++; + return E_FAIL; +} + +static const IDispatchVtbl dispeventVtbl = +{ + dispevent_QueryInterface, + dispevent_AddRef, + dispevent_Release, + dispevent_GetTypeInfoCount, + dispevent_GetTypeInfo, + dispevent_GetIDsOfNames, + dispevent_Invoke +}; + +static IDispatch* create_dispevent(void) +{ + dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event)); + + event->lpVtbl = &dispeventVtbl; + event->ref = 1; + + return (IDispatch*)&event->lpVtbl; +} + + static const WCHAR szEmpty[] = { 0 }; static const WCHAR szIncomplete[] = { '<','?','x','m','l',' ', @@ -3082,7 +3193,8 @@ static void test_XMLHTTP(void) VARIANT dummy; VARIANT async; VARIANT varbody; - LONG state, status; + LONG state, status, ref; + IDispatch *event; HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest, (void **)&pXMLHttpRequest); @@ -3104,6 +3216,13 @@ static void test_XMLHTTP(void) method = SysAllocString(wszPOST); url = SysAllocString(wszUrl);
+if (0) +{ + /* crashes on win98 */ + hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); +} + /* send before open */ hr = IXMLHttpRequest_send(pXMLHttpRequest, dummy); ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win9x, win2k */, "got 0x%08x\n", hr); @@ -3147,9 +3266,26 @@ static void test_XMLHTTP(void) ok(hr == S_OK, "got 0x%08x\n", hr); ok(state == 0, "got %d, expected 0\n", state);
+ event = create_dispevent(); + ref = IDispatch_AddRef(event); + ok(ref == 2, "got %d\n", ref); + IDispatch_Release(event); + + hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, event); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ref = IDispatch_AddRef(event); + ok(ref == 3, "got %d\n", ref); + IDispatch_Release(event); + + g_unexpectedcall = g_expectedcall = 0; + hr = IXMLHttpRequest_open(pXMLHttpRequest, method, url, async, dummy, dummy); ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(g_unexpectedcall == 0, "unexpected disp event call\n"); + ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n"); + /* status code after ::open() */ status = 0xdeadbeef; hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status); @@ -3225,6 +3361,7 @@ todo_wine {
SysFreeString(url);
+ IDispatch_Release(event); IXMLHttpRequest_Release(pXMLHttpRequest); free_bstrs(); }