msxml3: Add support for accessing document node.
[wine] / dlls / msxml3 / domimpl.c
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 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "msxml2.h"
31
32 #include "msxml_private.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
37
38 #ifdef HAVE_LIBXML2
39
40 typedef struct _domimpl
41 {
42     const struct IXMLDOMImplementationVtbl *lpVtbl;
43     LONG ref;
44 } domimpl;
45
46 static inline domimpl *impl_from_IXMLDOMImplementation( IXMLDOMImplementation *iface )
47 {
48     return (domimpl *)((char*)iface - FIELD_OFFSET(domimpl, lpVtbl));
49 }
50
51 static HRESULT WINAPI dimimpl_QueryInterface(
52     IXMLDOMImplementation *iface,
53     REFIID riid,
54     void** ppvObject )
55 {
56     domimpl *This = impl_from_IXMLDOMImplementation( iface );
57     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
58
59     if ( IsEqualGUID( riid, &IID_IXMLDOMImplementation ) ||
60          IsEqualGUID( riid, &IID_IDispatch ) ||
61          IsEqualGUID( riid, &IID_IUnknown ) )
62     {
63         *ppvObject = iface;
64     }
65     else
66     {
67         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
68         return E_NOINTERFACE;
69     }
70
71     IXMLDOMImplementation_AddRef( iface );
72
73     return S_OK;
74 }
75
76 static ULONG WINAPI dimimpl_AddRef(
77     IXMLDOMImplementation *iface )
78 {
79     domimpl *This = impl_from_IXMLDOMImplementation( iface );
80     return InterlockedIncrement( &This->ref );
81 }
82
83 static ULONG WINAPI dimimpl_Release(
84     IXMLDOMImplementation *iface )
85 {
86     domimpl *This = impl_from_IXMLDOMImplementation( iface );
87     ULONG ref;
88
89     ref = InterlockedDecrement( &This->ref );
90     if ( ref == 0 )
91     {
92         HeapFree( GetProcessHeap(), 0, This );
93     }
94
95     return ref;
96 }
97
98 static HRESULT WINAPI dimimpl_GetTypeInfoCount(
99     IXMLDOMImplementation *iface,
100     UINT* pctinfo )
101 {
102     domimpl *This = impl_from_IXMLDOMImplementation( iface );
103
104     TRACE("(%p)->(%p)\n", This, pctinfo);
105
106     *pctinfo = 1;
107
108     return S_OK;
109 }
110
111 static HRESULT WINAPI dimimpl_GetTypeInfo(
112     IXMLDOMImplementation *iface,
113     UINT iTInfo, LCID lcid,
114     ITypeInfo** ppTInfo )
115 {
116     domimpl *This = impl_from_IXMLDOMImplementation( iface );
117     HRESULT hr;
118
119     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
120
121     hr = get_typeinfo(IXMLDOMImplementation_tid, ppTInfo);
122
123     return hr;
124 }
125
126 static HRESULT WINAPI dimimpl_GetIDsOfNames(
127     IXMLDOMImplementation *iface,
128     REFIID riid, LPOLESTR* rgszNames,
129     UINT cNames, LCID lcid, DISPID* rgDispId )
130 {
131     domimpl *This = impl_from_IXMLDOMImplementation( iface );
132     ITypeInfo *typeinfo;
133     HRESULT hr;
134
135     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
136           lcid, rgDispId);
137
138     if(!rgszNames || cNames == 0 || !rgDispId)
139         return E_INVALIDARG;
140
141     hr = get_typeinfo(IXMLDOMImplementation_tid, &typeinfo);
142     if(SUCCEEDED(hr))
143     {
144         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
145         ITypeInfo_Release(typeinfo);
146     }
147
148     return hr;
149 }
150
151 static HRESULT WINAPI dimimpl_Invoke(
152     IXMLDOMImplementation *iface,
153     DISPID dispIdMember, REFIID riid, LCID lcid,
154     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
155     EXCEPINFO* pExcepInfo, UINT* puArgErr )
156 {
157     domimpl *This = impl_from_IXMLDOMImplementation( iface );
158     ITypeInfo *typeinfo;
159     HRESULT hr;
160
161     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
162           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
163
164     hr = get_typeinfo(IXMLDOMImplementation_tid, &typeinfo);
165     if(SUCCEEDED(hr))
166     {
167         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
168                 pVarResult, pExcepInfo, puArgErr);
169         ITypeInfo_Release(typeinfo);
170     }
171
172     return hr;
173 }
174
175 static HRESULT WINAPI dimimpl_hasFeature(IXMLDOMImplementation* This, BSTR feature, BSTR version, VARIANT_BOOL *hasFeature)
176 {
177     static const WCHAR bVersion[] = {'1','.','0',0};
178     static const WCHAR bXML[] = {'X','M','L',0};
179     static const WCHAR bDOM[] = {'D','O','M',0};
180     static const WCHAR bMSDOM[] = {'M','S','-','D','O','M',0};
181     BOOL bValidFeature = FALSE;
182     BOOL bValidVersion = FALSE;
183
184     TRACE("feature(%s) version (%s)\n", debugstr_w(feature), debugstr_w(version));
185
186     if(!feature || !hasFeature)
187         return E_INVALIDARG;
188
189     *hasFeature = VARIANT_FALSE;
190
191     if(!version || lstrcmpiW(version, bVersion) == 0)
192         bValidVersion = TRUE;
193
194     if(lstrcmpiW(feature, bXML) == 0 || lstrcmpiW(feature, bDOM) == 0 || lstrcmpiW(feature, bMSDOM) == 0)
195         bValidFeature = TRUE;
196
197     if(bValidVersion && bValidFeature)
198         *hasFeature = VARIANT_TRUE;
199
200     return S_OK;
201 }
202
203 static const struct IXMLDOMImplementationVtbl dimimpl_vtbl =
204 {
205     dimimpl_QueryInterface,
206     dimimpl_AddRef,
207     dimimpl_Release,
208     dimimpl_GetTypeInfoCount,
209     dimimpl_GetTypeInfo,
210     dimimpl_GetIDsOfNames,
211     dimimpl_Invoke,
212     dimimpl_hasFeature
213 };
214
215 IUnknown* create_doc_Implementation(void)
216 {
217     domimpl *This;
218
219     This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
220     if ( !This )
221         return NULL;
222
223     This->lpVtbl = &dimimpl_vtbl;
224     This->ref = 1;
225
226     return (IUnknown*) &This->lpVtbl;
227 }
228
229 #endif