msxml3: Store class version for MXWriter instance.
[wine/multimedia.git] / dlls / msxml3 / factory.c
blob2d1a42f8b196cb9cafb9294d3a811f79ae5dd1c1
1 /*
2 * MSXML Class Factory
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2005 Mike McCormack
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include "config.h"
26 #include <stdarg.h>
27 #ifdef HAVE_LIBXML2
28 # include <libxml/parser.h>
29 # include <libxml/xmlerror.h>
30 #endif
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "ole2.h"
36 #include "msxml.h"
37 #include "msxml2.h"
39 /* undef the #define in msxml2 so that we can access the v.2 version
40 independent CLSID as well as the v.3 one. */
41 #undef CLSID_DOMDocument
43 #include "wine/debug.h"
45 #include "msxml_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
49 typedef HRESULT (*ClassFactoryCreateInstanceFunc)(IUnknown*, void**);
50 typedef HRESULT (*DOMFactoryCreateInstanceFunc)(MSXML_VERSION, IUnknown*, void**);
52 struct clsid_version_t
54 const GUID *clsid;
55 MSXML_VERSION version;
58 static const struct clsid_version_t clsid_versions_table[] =
60 { &CLSID_DOMDocument, MSXML_DEFAULT },
61 { &CLSID_DOMDocument2, MSXML_DEFAULT },
62 { &CLSID_DOMDocument26, MSXML_DEFAULT },
63 { &CLSID_DOMDocument30, MSXML3 },
64 { &CLSID_DOMDocument40, MSXML4 },
65 { &CLSID_DOMDocument60, MSXML6 },
67 { &CLSID_DOMFreeThreadedDocument, MSXML_DEFAULT },
68 { &CLSID_FreeThreadedDOMDocument, MSXML_DEFAULT },
69 { &CLSID_FreeThreadedDOMDocument26, MSXML_DEFAULT },
70 { &CLSID_FreeThreadedDOMDocument30, MSXML3 },
71 { &CLSID_FreeThreadedDOMDocument40, MSXML4 },
72 { &CLSID_FreeThreadedDOMDocument60, MSXML6 },
74 { &CLSID_XMLSchemaCache, MSXML_DEFAULT },
75 { &CLSID_XMLSchemaCache26, MSXML_DEFAULT },
76 { &CLSID_XMLSchemaCache30, MSXML3 },
77 { &CLSID_XMLSchemaCache40, MSXML4 },
78 { &CLSID_XMLSchemaCache60, MSXML6 },
80 { &CLSID_MXXMLWriter, MSXML_DEFAULT },
81 { &CLSID_MXXMLWriter30, MSXML3 },
82 { &CLSID_MXXMLWriter40, MSXML4 },
83 { &CLSID_MXXMLWriter60, MSXML6 }
86 static MSXML_VERSION get_msxml_version(const GUID *clsid)
88 int i;
90 for (i = 0; i < sizeof(clsid_versions_table)/sizeof(struct clsid_version_t); i++)
91 if (IsEqualGUID(clsid, clsid_versions_table[i].clsid))
92 return clsid_versions_table[i].version;
94 ERR("unknown clsid=%s\n", debugstr_guid(clsid));
95 return MSXML_DEFAULT;
98 /******************************************************************************
99 * MSXML ClassFactory
101 typedef struct
103 IClassFactory IClassFactory_iface;
104 ClassFactoryCreateInstanceFunc pCreateInstance;
105 } ClassFactory;
107 typedef struct
109 IClassFactory IClassFactory_iface;
110 LONG ref;
111 DOMFactoryCreateInstanceFunc pCreateInstance;
112 MSXML_VERSION version;
113 } DOMFactory;
115 static inline ClassFactory *ClassFactory_from_IClassFactory(IClassFactory *iface)
117 return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
120 static HRESULT WINAPI ClassFactory_QueryInterface(
121 IClassFactory *iface,
122 REFIID riid,
123 void **ppobj )
125 if (IsEqualGUID(riid, &IID_IUnknown) ||
126 IsEqualGUID(riid, &IID_IClassFactory))
128 IClassFactory_AddRef( iface );
129 *ppobj = iface;
130 return S_OK;
133 FIXME("interface %s not implemented\n", debugstr_guid(riid));
134 *ppobj = NULL;
135 return E_NOINTERFACE;
138 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface )
140 return 2;
143 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface )
145 return 1;
148 static HRESULT WINAPI ClassFactory_CreateInstance(
149 IClassFactory *iface,
150 IUnknown *pOuter,
151 REFIID riid,
152 void **ppobj )
154 ClassFactory *This = ClassFactory_from_IClassFactory(iface);
155 IUnknown *punk;
156 HRESULT r;
158 TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
160 *ppobj = NULL;
162 if (pOuter)
163 return CLASS_E_NOAGGREGATION;
165 r = This->pCreateInstance( pOuter, (void**) &punk );
166 if (FAILED(r))
167 return r;
169 r = IUnknown_QueryInterface( punk, riid, ppobj );
170 IUnknown_Release( punk );
171 return r;
174 static HRESULT WINAPI ClassFactory_LockServer(
175 IClassFactory *iface,
176 BOOL dolock)
178 FIXME("(%p)->(%d),stub!\n",iface,dolock);
179 return S_OK;
182 static inline DOMFactory *DOMFactory_from_IClassFactory(IClassFactory *iface)
184 return CONTAINING_RECORD(iface, DOMFactory, IClassFactory_iface);
187 static ULONG WINAPI DOMClassFactory_AddRef(IClassFactory *iface )
189 DOMFactory *This = DOMFactory_from_IClassFactory(iface);
190 ULONG ref = InterlockedIncrement(&This->ref);
191 TRACE("(%p) ref = %u\n", This, ref);
192 return ref;
195 static ULONG WINAPI DOMClassFactory_Release(IClassFactory *iface )
197 DOMFactory *This = DOMFactory_from_IClassFactory(iface);
198 ULONG ref = InterlockedDecrement(&This->ref);
199 TRACE("(%p) ref = %u\n", This, ref);
200 if(!ref) {
201 heap_free(This);
203 return ref;
206 static HRESULT WINAPI DOMClassFactory_CreateInstance(
207 IClassFactory *iface,
208 IUnknown *pOuter,
209 REFIID riid,
210 void **ppobj )
212 DOMFactory *This = DOMFactory_from_IClassFactory(iface);
213 IUnknown *punk;
214 HRESULT r;
216 TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
218 *ppobj = NULL;
220 if (pOuter)
221 return CLASS_E_NOAGGREGATION;
223 r = This->pCreateInstance( This->version, pOuter, (void**) &punk );
224 if (FAILED(r))
225 return r;
227 r = IUnknown_QueryInterface( punk, riid, ppobj );
228 IUnknown_Release( punk );
229 return r;
232 static const struct IClassFactoryVtbl ClassFactoryVtbl =
234 ClassFactory_QueryInterface,
235 ClassFactory_AddRef,
236 ClassFactory_Release,
237 ClassFactory_CreateInstance,
238 ClassFactory_LockServer
241 static const struct IClassFactoryVtbl DOMClassFactoryVtbl =
243 ClassFactory_QueryInterface,
244 DOMClassFactory_AddRef,
245 DOMClassFactory_Release,
246 DOMClassFactory_CreateInstance,
247 ClassFactory_LockServer
250 static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv, DOMFactoryCreateInstanceFunc fnCreateInstance)
252 DOMFactory *ret = heap_alloc(sizeof(DOMFactory));
253 HRESULT hres;
255 ret->IClassFactory_iface.lpVtbl = &DOMClassFactoryVtbl;
256 ret->ref = 0;
257 ret->version = get_msxml_version(clsid);
258 ret->pCreateInstance = fnCreateInstance;
260 hres = IClassFactory_QueryInterface(&ret->IClassFactory_iface, riid, ppv);
261 if(FAILED(hres)) {
262 heap_free(ret);
263 *ppv = NULL;
265 return hres;
268 static ClassFactory xmldoccf = { { &ClassFactoryVtbl }, XMLDocument_create };
269 static ClassFactory saxreadcf = { { &ClassFactoryVtbl }, SAXXMLReader_create };
270 static ClassFactory httpreqcf = { { &ClassFactoryVtbl }, XMLHTTPRequest_create };
271 static ClassFactory xsltemplatecf = { { &ClassFactoryVtbl }, XSLTemplate_create };
272 static ClassFactory mxnsmanagercf = { {&ClassFactoryVtbl }, MXNamespaceManager_create };
274 /******************************************************************
275 * DllGetClassObject (MSXML3.@)
277 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
279 IClassFactory *cf = NULL;
281 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv );
283 if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */
284 IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */
285 IsEqualCLSID( rclsid, &CLSID_DOMDocument26 )|| /* Version dep. v 2.6 */
286 IsEqualCLSID( rclsid, &CLSID_DOMDocument30 )|| /* Version dep. v 3.0 */
287 IsEqualCLSID( rclsid, &CLSID_DOMDocument40 )|| /* Version dep. v 4.0 */
288 IsEqualCLSID( rclsid, &CLSID_DOMDocument60 )) /* Version dep. v 6.0 */
290 return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
292 else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) ||
293 IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache26 ) ||
294 IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ||
295 IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache40 ) ||
296 IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache60 ))
298 return DOMClassFactory_Create(rclsid, riid, ppv, SchemaCache_create);
300 else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
302 cf = &xmldoccf.IClassFactory_iface;
304 else if( IsEqualCLSID( rclsid, &CLSID_DOMFreeThreadedDocument ) || /* Version indep. v 2.x */
305 IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument ) ||
306 IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument26 ) ||
307 IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument30 ) ||
308 IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) ||
309 IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 ))
311 return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
313 else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
314 IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
315 IsEqualCLSID( rclsid, &CLSID_SAXXMLReader40 ) ||
316 IsEqualCLSID( rclsid, &CLSID_SAXXMLReader60 ))
318 cf = &saxreadcf.IClassFactory_iface;
320 else if( IsEqualCLSID( rclsid, &CLSID_XMLHTTPRequest ) ||
321 IsEqualCLSID( rclsid, &CLSID_XMLHTTP) ||
322 IsEqualCLSID( rclsid, &CLSID_XMLHTTP26 ) ||
323 IsEqualCLSID( rclsid, &CLSID_XMLHTTP30 ) ||
324 IsEqualCLSID( rclsid, &CLSID_XMLHTTP40 ) ||
325 IsEqualCLSID( rclsid, &CLSID_XMLHTTP60 ))
327 cf = &httpreqcf.IClassFactory_iface;
329 else if( IsEqualCLSID( rclsid, &CLSID_XSLTemplate ) ||
330 IsEqualCLSID( rclsid, &CLSID_XSLTemplate26 ) ||
331 IsEqualCLSID( rclsid, &CLSID_XSLTemplate30 ) ||
332 IsEqualCLSID( rclsid, &CLSID_XSLTemplate40 ) ||
333 IsEqualCLSID( rclsid, &CLSID_XSLTemplate60 ))
335 cf = &xsltemplatecf.IClassFactory_iface;
337 else if( IsEqualCLSID( rclsid, &CLSID_MXXMLWriter ) ||
338 IsEqualCLSID( rclsid, &CLSID_MXXMLWriter30 ) ||
339 IsEqualCLSID( rclsid, &CLSID_MXXMLWriter40 ) ||
340 IsEqualCLSID( rclsid, &CLSID_MXXMLWriter60 ) )
342 return DOMClassFactory_Create(rclsid, riid, ppv, MXWriter_create);
344 else if( IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager ) ||
345 IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager40 ) ||
346 IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager60 ) )
348 cf = &mxnsmanagercf.IClassFactory_iface;
351 if ( !cf )
352 return CLASS_E_CLASSNOTAVAILABLE;
354 return IClassFactory_QueryInterface( cf, riid, ppv );