1 /* 2 * DOM Document Implementation implementation 3 * 4 * Copyright 2007 Alistair Leslie-Hughes 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 #endif 30 31 #include "windef.h" 32 #include "winbase.h" 33 #include "winuser.h" 34 #include "ole2.h" 35 #include "msxml6.h" 36 37 #include "msxml_private.h" 38 39 #include "wine/debug.h" 40 41 #ifdef HAVE_LIBXML2 42 43 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 44 45 typedef struct _domimpl 46 { 47 DispatchEx dispex; 48 IXMLDOMImplementation IXMLDOMImplementation_iface; 49 LONG ref; 50 } domimpl; 51 52 static inline domimpl *impl_from_IXMLDOMImplementation( IXMLDOMImplementation *iface ) 53 { 54 return CONTAINING_RECORD(iface, domimpl, IXMLDOMImplementation_iface); 55 } 56 57 static HRESULT WINAPI dimimpl_QueryInterface( 58 IXMLDOMImplementation *iface, 59 REFIID riid, 60 void** ppvObject ) 61 { 62 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 63 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 64 65 if ( IsEqualGUID( riid, &IID_IXMLDOMImplementation ) || 66 IsEqualGUID( riid, &IID_IDispatch ) || 67 IsEqualGUID( riid, &IID_IUnknown ) ) 68 { 69 *ppvObject = iface; 70 } 71 else if (dispex_query_interface(&This->dispex, riid, ppvObject)) 72 { 73 return *ppvObject ? S_OK : E_NOINTERFACE; 74 } 75 else 76 { 77 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 78 *ppvObject = NULL; 79 return E_NOINTERFACE; 80 } 81 82 IXMLDOMImplementation_AddRef( iface ); 83 84 return S_OK; 85 } 86 87 static ULONG WINAPI dimimpl_AddRef( 88 IXMLDOMImplementation *iface ) 89 { 90 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 91 ULONG ref = InterlockedIncrement( &This->ref ); 92 TRACE("(%p)->(%d)\n", This, ref); 93 return ref; 94 } 95 96 static ULONG WINAPI dimimpl_Release( 97 IXMLDOMImplementation *iface ) 98 { 99 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 100 ULONG ref = InterlockedDecrement( &This->ref ); 101 102 TRACE("(%p)->(%d)\n", This, ref); 103 if ( ref == 0 ) 104 heap_free( This ); 105 106 return ref; 107 } 108 109 static HRESULT WINAPI dimimpl_GetTypeInfoCount( 110 IXMLDOMImplementation *iface, 111 UINT* pctinfo ) 112 { 113 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 114 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); 115 } 116 117 static HRESULT WINAPI dimimpl_GetTypeInfo( 118 IXMLDOMImplementation *iface, 119 UINT iTInfo, LCID lcid, 120 ITypeInfo** ppTInfo ) 121 { 122 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 123 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, 124 iTInfo, lcid, ppTInfo); 125 } 126 127 static HRESULT WINAPI dimimpl_GetIDsOfNames( 128 IXMLDOMImplementation *iface, 129 REFIID riid, LPOLESTR* rgszNames, 130 UINT cNames, LCID lcid, DISPID* rgDispId ) 131 { 132 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 133 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, 134 riid, rgszNames, cNames, lcid, rgDispId); 135 } 136 137 static HRESULT WINAPI dimimpl_Invoke( 138 IXMLDOMImplementation *iface, 139 DISPID dispIdMember, REFIID riid, LCID lcid, 140 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 141 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 142 { 143 domimpl *This = impl_from_IXMLDOMImplementation( iface ); 144 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, 145 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 146 } 147 148 static HRESULT WINAPI dimimpl_hasFeature(IXMLDOMImplementation* This, BSTR feature, BSTR version, VARIANT_BOOL *hasFeature) 149 { 150 static const WCHAR bVersion[] = {'1','.','0',0}; 151 static const WCHAR bXML[] = {'X','M','L',0}; 152 static const WCHAR bDOM[] = {'D','O','M',0}; 153 static const WCHAR bMSDOM[] = {'M','S','-','D','O','M',0}; 154 BOOL bValidFeature = FALSE; 155 BOOL bValidVersion = FALSE; 156 157 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(feature), debugstr_w(version), hasFeature); 158 159 if(!feature || !hasFeature) 160 return E_INVALIDARG; 161 162 *hasFeature = VARIANT_FALSE; 163 164 if(!version || lstrcmpiW(version, bVersion) == 0) 165 bValidVersion = TRUE; 166 167 if(lstrcmpiW(feature, bXML) == 0 || lstrcmpiW(feature, bDOM) == 0 || lstrcmpiW(feature, bMSDOM) == 0) 168 bValidFeature = TRUE; 169 170 if(bValidVersion && bValidFeature) 171 *hasFeature = VARIANT_TRUE; 172 173 return S_OK; 174 } 175 176 static const struct IXMLDOMImplementationVtbl dimimpl_vtbl = 177 { 178 dimimpl_QueryInterface, 179 dimimpl_AddRef, 180 dimimpl_Release, 181 dimimpl_GetTypeInfoCount, 182 dimimpl_GetTypeInfo, 183 dimimpl_GetIDsOfNames, 184 dimimpl_Invoke, 185 dimimpl_hasFeature 186 }; 187 188 static const tid_t dimimpl_iface_tids[] = { 189 IXMLDOMImplementation_tid, 190 0 191 }; 192 193 static dispex_static_data_t dimimpl_dispex = { 194 NULL, 195 IXMLDOMImplementation_tid, 196 NULL, 197 dimimpl_iface_tids 198 }; 199 200 IUnknown* create_doc_Implementation(void) 201 { 202 domimpl *This; 203 204 This = heap_alloc( sizeof *This ); 205 if ( !This ) 206 return NULL; 207 208 This->IXMLDOMImplementation_iface.lpVtbl = &dimimpl_vtbl; 209 This->ref = 1; 210 init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMImplementation_iface, &dimimpl_dispex); 211 212 return (IUnknown*)&This->IXMLDOMImplementation_iface; 213 } 214 215 #endif 216