diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c index e3b910a070e..256bbbd877d 100644 --- a/dlls/msxml3/factory.c +++ b/dlls/msxml3/factory.c @@ -86,7 +86,12 @@ static const struct clsid_version_t clsid_versions_table[] = { &CLSID_SAXXMLReader, MSXML_DEFAULT }, { &CLSID_SAXXMLReader30, MSXML3 }, { &CLSID_SAXXMLReader40, MSXML4 }, - { &CLSID_SAXXMLReader60, MSXML6 } + { &CLSID_SAXXMLReader60, MSXML6 }, + + { &CLSID_SAXAttributes, MSXML_DEFAULT }, + { &CLSID_SAXAttributes30, MSXML3 }, + { &CLSID_SAXAttributes40, MSXML4 }, + { &CLSID_SAXAttributes60, MSXML6 } }; static MSXML_VERSION get_msxml_version(const GUID *clsid) @@ -347,6 +352,13 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv ) { return DOMClassFactory_Create(rclsid, riid, ppv, MXWriter_create); } + else if( IsEqualCLSID( rclsid, &CLSID_SAXAttributes) || + IsEqualCLSID( rclsid, &CLSID_SAXAttributes30 ) || + IsEqualCLSID( rclsid, &CLSID_SAXAttributes40 ) || + IsEqualCLSID( rclsid, &CLSID_SAXAttributes60 )) + { + return DOMClassFactory_Create(rclsid, riid, ppv, SAXAttributes_create); + } else if( IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager ) || IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager40 ) || IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager60 ) ) diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index e51501bfb8f..27c4d7f8221 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -453,6 +453,7 @@ extern HRESULT DOMDocument_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HID extern HRESULT SchemaCache_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN; extern HRESULT XMLDocument_create(IUnknown*, void**) DECLSPEC_HIDDEN; extern HRESULT SAXXMLReader_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN; +extern HRESULT SAXAttributes_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN; extern HRESULT XMLHTTPRequest_create(IUnknown*, void **) DECLSPEC_HIDDEN; extern HRESULT XSLTemplate_create(IUnknown*, void**) DECLSPEC_HIDDEN; extern HRESULT MXWriter_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN; diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c index 55159e166ba..dabd3d66161 100644 --- a/dlls/msxml3/mxwriter.c +++ b/dlls/msxml3/mxwriter.c @@ -118,6 +118,18 @@ typedef struct output_buffer *buffer; } mxwriter; +typedef struct +{ + DispatchEx dispex; + IMXAttributes IMXAttributes_iface; + LONG ref; +} mxattributes; + +static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface ) +{ + return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface); +} + static xml_encoding parse_encoding_name(const WCHAR *encoding) { static const WCHAR utf8W[] = {'U','T','F','-','8',0}; @@ -1436,3 +1448,227 @@ HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **ppObj) return S_OK; } + +static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj); + + *ppObj = NULL; + + if ( IsEqualGUID( riid, &IID_IUnknown ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IMXAttributes )) + { + *ppObj = iface; + } + else if (dispex_query_interface(&This->dispex, riid, ppObj)) + { + return *ppObj ? S_OK : E_NOINTERFACE; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IMXAttributes_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + ULONG ref = InterlockedIncrement( &This->ref ); + TRACE("(%p)->(%d)\n", This, ref ); + return ref; +} + +static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + LONG ref = InterlockedDecrement( &This->ref ); + + TRACE("(%p)->(%d)\n", This, ref); + + if (ref == 0) + { + release_dispex(&This->dispex); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI MXAttributes_GetIDsOfNames( + IMXAttributes *iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, + riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI MXAttributes_Invoke( + IMXAttributes *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, + dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface, + BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%s %s %s %s %s): stub\n", This, debugstr_w(uri), debugstr_w(localName), + debugstr_w(QName), debugstr_w(type), debugstr_w(value)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface, + VARIANT atts, int index) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d): stub\n", This, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index, + BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri), + debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index, + BSTR localName) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(localName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(QName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(uri)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value) +{ + mxattributes *This = impl_from_IMXAttributes( iface ); + FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(value)); + return E_NOTIMPL; +} + +static const IMXAttributesVtbl MXAttributesVtbl = { + MXAttributes_QueryInterface, + MXAttributes_AddRef, + MXAttributes_Release, + MXAttributes_GetTypeInfoCount, + MXAttributes_GetTypeInfo, + MXAttributes_GetIDsOfNames, + MXAttributes_Invoke, + MXAttributes_addAttribute, + MXAttributes_addAttributeFromIndex, + MXAttributes_clear, + MXAttributes_removeAttribute, + MXAttributes_setAttribute, + MXAttributes_setAttributes, + MXAttributes_setLocalName, + MXAttributes_setQName, + MXAttributes_setURI, + MXAttributes_setValue +}; + +static const tid_t mxattrs_iface_tids[] = { + IMXAttributes_tid, + 0 +}; + +static dispex_static_data_t mxattrs_dispex = { + NULL, + IMXAttributes_tid, + NULL, + mxattrs_iface_tids +}; + +HRESULT SAXAttributes_create(MSXML_VERSION version, IUnknown *outer, void **ppObj) +{ + mxattributes *This; + + TRACE("(%p, %p)\n", outer, ppObj); + + This = heap_alloc( sizeof (*This) ); + if( !This ) + return E_OUTOFMEMORY; + + This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl; + This->ref = 1; + + *ppObj = &This->IMXAttributes_iface; + + init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex); + + TRACE("returning iface %p\n", *ppObj); + + return S_OK; +} diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 494d86638db..28522d81828 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -449,8 +449,12 @@ static HRESULT WINAPI contentHandler_startElement( int nQName, ISAXAttributes *pAttr) { - int len; + IMXAttributes *mxattr; HRESULT hres; + int len; + + hres = ISAXAttributes_QueryInterface(pAttr, &IID_IMXAttributes, (void**)&mxattr); + EXPECT_HR(hres, E_NOINTERFACE); if(!test_expect_call(CH_STARTELEMENT)) return E_FAIL; @@ -3309,7 +3313,15 @@ static void test_mxattr_addAttribute(void) EXPECT_HR(hr, S_OK); hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr); +todo_wine EXPECT_HR(hr, S_OK); + if (hr != S_OK) + { + IMXAttributes_Release(mxattr); + table++; + i++; + continue; + } /* SAXAttributes30 and SAXAttributes60 both crash on this test */ if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) || @@ -3359,7 +3371,13 @@ static void test_mxattr_clear(void) EXPECT_HR(hr, S_OK); hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr); +todo_wine EXPECT_HR(hr, S_OK); + if (hr != S_OK) + { + IMXAttributes_Release(mxattr); + return; + } hr = ISAXAttributes_getQName(saxattr, 0, NULL, NULL); EXPECT_HR(hr, E_INVALIDARG); @@ -3412,6 +3430,27 @@ static void test_mxattr_clear(void) free_bstrs(); } +static void test_mxattr_dispex(void) +{ + IMXAttributes *mxattr; + IDispatchEx *dispex; + IUnknown *unk; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_SAXAttributes, NULL, CLSCTX_INPROC_SERVER, + &IID_IMXAttributes, (void**)&mxattr); + EXPECT_HR(hr, S_OK); + + hr = IMXAttributes_QueryInterface(mxattr, &IID_IDispatchEx, (void**)&dispex); + EXPECT_HR(hr, S_OK); + hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk); + test_obj_dispex(unk); + IUnknown_Release(unk); + IDispatchEx_Release(dispex); + + IMXAttributes_Release(mxattr); +} + START_TEST(saxreader) { ISAXXMLReader *reader; @@ -3465,6 +3504,7 @@ START_TEST(saxreader) { test_mxattr_addAttribute(); test_mxattr_clear(); + test_mxattr_dispex(); } else skip("SAXAttributes not supported\n");