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
25 #include <libxml/parser.h>
26 #include <libxml/xmlerror.h>
34 #include "xmlparser.h"
36 /* undef the #define in msxml2 so that we can access the v.2 version
37 independent CLSID as well as the v.3 one. */
38 #undef CLSID_DOMDocument
40 #include "wine/debug.h"
42 #include "msxml_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
46 typedef HRESULT (*ClassFactoryCreateInstanceFunc
)(void**);
47 typedef HRESULT (*DOMFactoryCreateInstanceFunc
)(MSXML_VERSION
, void**);
49 struct clsid_version_t
52 MSXML_VERSION version
;
55 static const struct clsid_version_t clsid_versions_table
[] =
57 { &CLSID_DOMDocument
, MSXML_DEFAULT
},
58 { &CLSID_DOMDocument2
, MSXML2
},
59 { &CLSID_DOMDocument26
, MSXML26
},
60 { &CLSID_DOMDocument30
, MSXML3
},
61 { &CLSID_DOMDocument40
, MSXML4
},
62 { &CLSID_DOMDocument60
, MSXML6
},
64 { &CLSID_DOMFreeThreadedDocument
, MSXML_DEFAULT
},
65 { &CLSID_FreeThreadedDOMDocument
, MSXML_DEFAULT
},
66 { &CLSID_FreeThreadedDOMDocument26
, MSXML26
},
67 { &CLSID_FreeThreadedDOMDocument30
, MSXML3
},
68 { &CLSID_FreeThreadedDOMDocument40
, MSXML4
},
69 { &CLSID_FreeThreadedDOMDocument60
, MSXML6
},
71 { &CLSID_XMLSchemaCache
, MSXML_DEFAULT
},
72 { &CLSID_XMLSchemaCache26
, MSXML26
},
73 { &CLSID_XMLSchemaCache30
, MSXML3
},
74 { &CLSID_XMLSchemaCache40
, MSXML4
},
75 { &CLSID_XMLSchemaCache60
, MSXML6
},
77 { &CLSID_MXXMLWriter
, MSXML_DEFAULT
},
78 { &CLSID_MXXMLWriter30
, MSXML3
},
79 { &CLSID_MXXMLWriter40
, MSXML4
},
80 { &CLSID_MXXMLWriter60
, MSXML6
},
82 { &CLSID_SAXXMLReader
, MSXML_DEFAULT
},
83 { &CLSID_SAXXMLReader30
, MSXML3
},
84 { &CLSID_SAXXMLReader40
, MSXML4
},
85 { &CLSID_SAXXMLReader60
, MSXML6
},
87 { &CLSID_SAXAttributes
, MSXML_DEFAULT
},
88 { &CLSID_SAXAttributes30
, MSXML3
},
89 { &CLSID_SAXAttributes40
, MSXML4
},
90 { &CLSID_SAXAttributes60
, MSXML6
},
92 { &CLSID_XMLView
, MSXML_DEFAULT
}
95 static MSXML_VERSION
get_msxml_version(const GUID
*clsid
)
99 for (i
= 0; i
< ARRAY_SIZE(clsid_versions_table
); i
++)
100 if (IsEqualGUID(clsid
, clsid_versions_table
[i
].clsid
))
101 return clsid_versions_table
[i
].version
;
103 ERR("unknown clsid=%s\n", debugstr_guid(clsid
));
104 return MSXML_DEFAULT
;
107 /******************************************************************************
112 IClassFactory IClassFactory_iface
;
113 ClassFactoryCreateInstanceFunc pCreateInstance
;
118 IClassFactory IClassFactory_iface
;
120 DOMFactoryCreateInstanceFunc pCreateInstance
;
121 MSXML_VERSION version
;
124 static inline ClassFactory
*ClassFactory_from_IClassFactory(IClassFactory
*iface
)
126 return CONTAINING_RECORD(iface
, ClassFactory
, IClassFactory_iface
);
129 static HRESULT WINAPI
ClassFactory_QueryInterface(
130 IClassFactory
*iface
,
134 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
135 IsEqualGUID(riid
, &IID_IClassFactory
))
137 IClassFactory_AddRef( iface
);
142 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
144 return E_NOINTERFACE
;
147 static ULONG WINAPI
ClassFactory_AddRef(IClassFactory
*iface
)
152 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
157 static HRESULT WINAPI
ClassFactory_CreateInstance(
158 IClassFactory
*iface
,
163 ClassFactory
*This
= ClassFactory_from_IClassFactory(iface
);
167 TRACE("%p %s %p\n", pOuter
, debugstr_guid(riid
), ppobj
);
172 return CLASS_E_NOAGGREGATION
;
174 r
= This
->pCreateInstance( (void**) &punk
);
178 r
= IUnknown_QueryInterface( punk
, riid
, ppobj
);
179 IUnknown_Release( punk
);
183 static HRESULT WINAPI
ClassFactory_LockServer(
184 IClassFactory
*iface
,
187 FIXME("(%p)->(%d),stub!\n",iface
,dolock
);
191 static inline DOMFactory
*DOMFactory_from_IClassFactory(IClassFactory
*iface
)
193 return CONTAINING_RECORD(iface
, DOMFactory
, IClassFactory_iface
);
196 static ULONG WINAPI
DOMClassFactory_AddRef(IClassFactory
*iface
)
198 DOMFactory
*factory
= DOMFactory_from_IClassFactory(iface
);
199 ULONG ref
= InterlockedIncrement(&factory
->ref
);
200 TRACE("%p, refcount %lu.\n", iface
, ref
);
204 static ULONG WINAPI
DOMClassFactory_Release(IClassFactory
*iface
)
206 DOMFactory
*factory
= DOMFactory_from_IClassFactory(iface
);
207 ULONG ref
= InterlockedDecrement(&factory
->ref
);
209 TRACE("%p, refcount %lu.\n", iface
, ref
);
217 static HRESULT WINAPI
DOMClassFactory_CreateInstance(
218 IClassFactory
*iface
,
223 DOMFactory
*This
= DOMFactory_from_IClassFactory(iface
);
227 TRACE("%p %s %p\n", pOuter
, debugstr_guid(riid
), ppobj
);
232 return CLASS_E_NOAGGREGATION
;
234 r
= This
->pCreateInstance( This
->version
, (void**) &punk
);
238 r
= IUnknown_QueryInterface( punk
, riid
, ppobj
);
239 IUnknown_Release( punk
);
243 static const struct IClassFactoryVtbl ClassFactoryVtbl
=
245 ClassFactory_QueryInterface
,
247 ClassFactory_Release
,
248 ClassFactory_CreateInstance
,
249 ClassFactory_LockServer
252 static const struct IClassFactoryVtbl DOMClassFactoryVtbl
=
254 ClassFactory_QueryInterface
,
255 DOMClassFactory_AddRef
,
256 DOMClassFactory_Release
,
257 DOMClassFactory_CreateInstance
,
258 ClassFactory_LockServer
261 static HRESULT
DOMClassFactory_Create(const GUID
*clsid
, REFIID riid
, void **ppv
, DOMFactoryCreateInstanceFunc fnCreateInstance
)
263 DOMFactory
*ret
= heap_alloc(sizeof(DOMFactory
));
266 ret
->IClassFactory_iface
.lpVtbl
= &DOMClassFactoryVtbl
;
268 ret
->version
= get_msxml_version(clsid
);
269 ret
->pCreateInstance
= fnCreateInstance
;
271 hres
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
279 static ClassFactory xmldoccf
= { { &ClassFactoryVtbl
}, XMLDocument_create
};
280 static ClassFactory httpreqcf
= { { &ClassFactoryVtbl
}, XMLHTTPRequest_create
};
281 static ClassFactory serverhttp
= { { &ClassFactoryVtbl
}, ServerXMLHTTP_create
};
282 static ClassFactory xsltemplatecf
= { { &ClassFactoryVtbl
}, XSLTemplate_create
};
283 static ClassFactory mxnsmanagercf
= { {&ClassFactoryVtbl
}, MXNamespaceManager_create
};
284 static ClassFactory xmlparsercf
= { { &ClassFactoryVtbl
}, XMLParser_create
};
285 static ClassFactory xmlviewcf
= { { &ClassFactoryVtbl
}, XMLView_create
};
287 /******************************************************************
288 * DllGetClassObject (MSXML3.@)
290 HRESULT WINAPI
DllGetClassObject( REFCLSID rclsid
, REFIID riid
, void **ppv
)
292 IClassFactory
*cf
= NULL
;
294 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
296 if( IsEqualCLSID( rclsid
, &CLSID_DOMDocument
) || /* Version indep. v 2.x */
297 IsEqualCLSID( rclsid
, &CLSID_DOMDocument2
) || /* Version indep. v 3.0 */
298 IsEqualCLSID( rclsid
, &CLSID_DOMDocument26
)|| /* Version dep. v 2.6 */
299 IsEqualCLSID( rclsid
, &CLSID_DOMDocument30
)|| /* Version dep. v 3.0 */
300 IsEqualCLSID( rclsid
, &CLSID_DOMDocument40
)|| /* Version dep. v 4.0 */
301 IsEqualCLSID( rclsid
, &CLSID_DOMDocument60
)) /* Version dep. v 6.0 */
303 return DOMClassFactory_Create(rclsid
, riid
, ppv
, dom_document_create
);
305 else if( IsEqualCLSID( rclsid
, &CLSID_XMLSchemaCache
) ||
306 IsEqualCLSID( rclsid
, &CLSID_XMLSchemaCache26
) ||
307 IsEqualCLSID( rclsid
, &CLSID_XMLSchemaCache30
) ||
308 IsEqualCLSID( rclsid
, &CLSID_XMLSchemaCache40
) ||
309 IsEqualCLSID( rclsid
, &CLSID_XMLSchemaCache60
))
311 return DOMClassFactory_Create(rclsid
, riid
, ppv
, SchemaCache_create
);
313 else if( IsEqualCLSID( rclsid
, &CLSID_XMLDocument
) )
315 cf
= &xmldoccf
.IClassFactory_iface
;
317 else if( IsEqualCLSID( rclsid
, &CLSID_DOMFreeThreadedDocument
) || /* Version indep. v 2.x */
318 IsEqualCLSID( rclsid
, &CLSID_FreeThreadedDOMDocument
) ||
319 IsEqualCLSID( rclsid
, &CLSID_FreeThreadedDOMDocument26
) ||
320 IsEqualCLSID( rclsid
, &CLSID_FreeThreadedDOMDocument30
) ||
321 IsEqualCLSID( rclsid
, &CLSID_FreeThreadedDOMDocument40
) ||
322 IsEqualCLSID( rclsid
, &CLSID_FreeThreadedDOMDocument60
))
324 return DOMClassFactory_Create(rclsid
, riid
, ppv
, dom_document_create
);
326 else if( IsEqualCLSID( rclsid
, &CLSID_SAXXMLReader
) ||
327 IsEqualCLSID( rclsid
, &CLSID_SAXXMLReader30
) ||
328 IsEqualCLSID( rclsid
, &CLSID_SAXXMLReader40
) ||
329 IsEqualCLSID( rclsid
, &CLSID_SAXXMLReader60
))
331 return DOMClassFactory_Create(rclsid
, riid
, ppv
, SAXXMLReader_create
);
333 else if( IsEqualCLSID( rclsid
, &CLSID_XMLHTTPRequest
) ||
334 IsEqualCLSID( rclsid
, &CLSID_XMLHTTP
) ||
335 IsEqualCLSID( rclsid
, &CLSID_XMLHTTP26
) ||
336 IsEqualCLSID( rclsid
, &CLSID_XMLHTTP30
) ||
337 IsEqualCLSID( rclsid
, &CLSID_XMLHTTP40
) ||
338 IsEqualCLSID( rclsid
, &CLSID_XMLHTTP60
))
340 cf
= &httpreqcf
.IClassFactory_iface
;
342 else if( IsEqualCLSID( rclsid
, &CLSID_ServerXMLHTTP
) ||
343 IsEqualCLSID( rclsid
, &CLSID_ServerXMLHTTP30
) ||
344 IsEqualCLSID( rclsid
, &CLSID_ServerXMLHTTP40
) ||
345 IsEqualCLSID( rclsid
, &CLSID_ServerXMLHTTP60
))
347 cf
= &serverhttp
.IClassFactory_iface
;
349 else if( IsEqualCLSID( rclsid
, &CLSID_XSLTemplate
) ||
350 IsEqualCLSID( rclsid
, &CLSID_XSLTemplate26
) ||
351 IsEqualCLSID( rclsid
, &CLSID_XSLTemplate30
) ||
352 IsEqualCLSID( rclsid
, &CLSID_XSLTemplate40
) ||
353 IsEqualCLSID( rclsid
, &CLSID_XSLTemplate60
))
355 cf
= &xsltemplatecf
.IClassFactory_iface
;
357 else if( IsEqualCLSID( rclsid
, &CLSID_MXXMLWriter
) ||
358 IsEqualCLSID( rclsid
, &CLSID_MXXMLWriter30
) ||
359 IsEqualCLSID( rclsid
, &CLSID_MXXMLWriter40
) ||
360 IsEqualCLSID( rclsid
, &CLSID_MXXMLWriter60
) )
362 return DOMClassFactory_Create(rclsid
, riid
, ppv
, MXWriter_create
);
364 else if( IsEqualCLSID( rclsid
, &CLSID_SAXAttributes
) ||
365 IsEqualCLSID( rclsid
, &CLSID_SAXAttributes30
) ||
366 IsEqualCLSID( rclsid
, &CLSID_SAXAttributes40
) ||
367 IsEqualCLSID( rclsid
, &CLSID_SAXAttributes60
))
369 return DOMClassFactory_Create(rclsid
, riid
, ppv
, SAXAttributes_create
);
371 else if( IsEqualCLSID( rclsid
, &CLSID_MXNamespaceManager
) ||
372 IsEqualCLSID( rclsid
, &CLSID_MXNamespaceManager40
) ||
373 IsEqualCLSID( rclsid
, &CLSID_MXNamespaceManager60
) )
375 cf
= &mxnsmanagercf
.IClassFactory_iface
;
377 else if( IsEqualCLSID( rclsid
, &CLSID_XMLParser
) ||
378 IsEqualCLSID( rclsid
, &CLSID_XMLParser26
) ||
379 IsEqualCLSID( rclsid
, &CLSID_XMLParser30
) )
381 cf
= &xmlparsercf
.IClassFactory_iface
;
383 else if( IsEqualCLSID( rclsid
, &CLSID_XMLView
) )
385 cf
= &xmlviewcf
.IClassFactory_iface
;
389 return CLASS_E_CLASSNOTAVAILABLE
;
391 return IClassFactory_QueryInterface( cf
, riid
, ppv
);