msxml3: Include the system libxml headers before the Windows headers.
[wine] / dlls / msxml3 / factory.c
1 /*
2  *    MSXML Class Factory
3  *
4  * Copyright 2002 Lionel Ulmer
5  * Copyright 2005 Mike McCormack
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #define COBJMACROS
23
24 #include "config.h"
25
26 #include <stdarg.h>
27 #ifdef HAVE_LIBXML2
28 # include <libxml/parser.h>
29 # include <libxml/xmlerror.h>
30 #endif
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "ole2.h"
36 #include "msxml.h"
37 #include "msxml2.h"
38
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
42
43 #include "wine/debug.h"
44
45 #include "msxml_private.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
48
49 typedef HRESULT (*ClassFactoryCreateInstanceFunc)(IUnknown *pUnkOuter, LPVOID *ppObj);
50 typedef HRESULT (*DOMFactoryCreateInstanceFunc)(const GUID *clsid, IUnknown *pUnkOuter, LPVOID *ppObj);
51
52 /******************************************************************************
53  * MSXML ClassFactory
54  */
55 typedef struct
56 {
57     const struct IClassFactoryVtbl *lpVtbl;
58     ClassFactoryCreateInstanceFunc pCreateInstance;
59 } ClassFactory;
60
61 typedef struct
62 {
63     const struct IClassFactoryVtbl *lpVtbl;
64     LONG ref;
65     DOMFactoryCreateInstanceFunc pCreateInstance;
66     GUID clsid;
67 } DOMFactory;
68
69 static HRESULT WINAPI ClassFactory_QueryInterface(
70     IClassFactory *iface,
71     REFIID riid,
72     void **ppobj )
73 {
74     if (IsEqualGUID(riid, &IID_IUnknown) ||
75         IsEqualGUID(riid, &IID_IClassFactory))
76     {
77         IClassFactory_AddRef( iface );
78         *ppobj = iface;
79         return S_OK;
80     }
81
82     FIXME("interface %s not implemented\n", debugstr_guid(riid));
83     return E_NOINTERFACE;
84 }
85
86 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface )
87 {
88     return 2;
89 }
90
91 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface )
92 {
93     return 1;
94 }
95
96 static HRESULT WINAPI ClassFactory_CreateInstance(
97     IClassFactory *iface,
98     IUnknown *pOuter,
99     REFIID riid,
100     void **ppobj )
101 {
102     ClassFactory *This = (ClassFactory*)iface;
103     IUnknown *punk;
104     HRESULT r;
105
106     TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
107
108     *ppobj = NULL;
109
110     if (pOuter)
111         return CLASS_E_NOAGGREGATION;
112
113     r = This->pCreateInstance( pOuter, (void**) &punk );
114     if (FAILED(r))
115         return r;
116
117     r = IUnknown_QueryInterface( punk, riid, ppobj );
118     IUnknown_Release( punk );
119     return r;
120 }
121
122 static HRESULT WINAPI ClassFactory_LockServer(
123     IClassFactory *iface,
124     BOOL dolock)
125 {
126     FIXME("(%p)->(%d),stub!\n",iface,dolock);
127     return S_OK;
128 }
129
130 static ULONG WINAPI DOMClassFactory_AddRef(IClassFactory *iface )
131 {
132     DOMFactory *This = (DOMFactory*)iface;
133     ULONG ref = InterlockedIncrement(&This->ref);
134     TRACE("(%p) ref = %u\n", This, ref);
135     return ref;
136 }
137
138 static ULONG WINAPI DOMClassFactory_Release(IClassFactory *iface )
139 {
140     DOMFactory *This = (DOMFactory*)iface;
141     ULONG ref = InterlockedDecrement(&This->ref);
142     TRACE("(%p) ref = %u\n", This, ref);
143     if(!ref) {
144         heap_free(This);
145     }
146     return ref;
147 }
148
149 static HRESULT WINAPI DOMClassFactory_CreateInstance(
150     IClassFactory *iface,
151     IUnknown *pOuter,
152     REFIID riid,
153     void **ppobj )
154 {
155     DOMFactory *This = (DOMFactory*)iface;
156     IUnknown *punk;
157     HRESULT r;
158
159     TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
160
161     *ppobj = NULL;
162
163     if (pOuter)
164         return CLASS_E_NOAGGREGATION;
165
166     r = This->pCreateInstance( &This->clsid, pOuter, (void**) &punk );
167     if (FAILED(r))
168         return r;
169
170     r = IUnknown_QueryInterface( punk, riid, ppobj );
171     IUnknown_Release( punk );
172     return r;
173 }
174
175 static const struct IClassFactoryVtbl ClassFactoryVtbl =
176 {
177     ClassFactory_QueryInterface,
178     ClassFactory_AddRef,
179     ClassFactory_Release,
180     ClassFactory_CreateInstance,
181     ClassFactory_LockServer
182 };
183
184 static const struct IClassFactoryVtbl DOMClassFactoryVtbl =
185 {
186     ClassFactory_QueryInterface,
187     DOMClassFactory_AddRef,
188     DOMClassFactory_Release,
189     DOMClassFactory_CreateInstance,
190     ClassFactory_LockServer
191 };
192
193 static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv, DOMFactoryCreateInstanceFunc fnCreateInstance)
194 {
195     DOMFactory *ret = heap_alloc(sizeof(DOMFactory));
196     HRESULT hres;
197
198     ret->lpVtbl = &DOMClassFactoryVtbl;
199     ret->ref = 0;
200     ret->clsid = *clsid;
201     ret->pCreateInstance = fnCreateInstance;
202
203     hres = IClassFactory_QueryInterface((IClassFactory*)ret, riid, ppv);
204     if(FAILED(hres)) {
205         heap_free(ret);
206         *ppv = NULL;
207     }
208     return hres;
209 }
210
211 static ClassFactory xmldoccf = { &ClassFactoryVtbl, XMLDocument_create };
212 static ClassFactory saxreadcf = { &ClassFactoryVtbl, SAXXMLReader_create };
213 static ClassFactory httpreqcf = { &ClassFactoryVtbl, XMLHTTPRequest_create };
214 static ClassFactory xsltemplatecf = { &ClassFactoryVtbl, XSLTemplate_create };
215
216 /******************************************************************
217  *              DllGetClassObject (MSXML3.@)
218  */
219 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
220 {
221     IClassFactory *cf = NULL;
222
223     TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv );
224
225     if( IsEqualCLSID( rclsid, &CLSID_DOMDocument )  ||  /* Version indep. v 2.x */
226         IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) ||  /* Version indep. v 3.0 */
227         IsEqualCLSID( rclsid, &CLSID_DOMDocument26 )||  /* Version dep.   v 2.6 */
228         IsEqualCLSID( rclsid, &CLSID_DOMDocument30 )||  /* Version dep.   v 3.0 */
229         IsEqualCLSID( rclsid, &CLSID_DOMDocument40 )||  /* Version dep.   v 4.0 */
230         IsEqualCLSID( rclsid, &CLSID_DOMDocument60 ))   /* Version dep.   v 6.0 */
231     {
232         return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
233     }
234     else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache )   ||
235              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache26 ) ||
236              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ||
237              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache40 ) ||
238              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache60 ))
239     {
240         return DOMClassFactory_Create(rclsid, riid, ppv, SchemaCache_create);
241     }
242     else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
243     {
244         cf = (IClassFactory*) &xmldoccf.lpVtbl;
245     }
246     else if( IsEqualCLSID( rclsid, &CLSID_DOMFreeThreadedDocument )   ||   /* Version indep. v 2.x */
247              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument )   ||
248              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument26 ) ||
249              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument30 ) ||
250              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) ||
251              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 ))
252     {
253         return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
254     }
255     else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
256              IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
257              IsEqualCLSID( rclsid, &CLSID_SAXXMLReader40 ) ||
258              IsEqualCLSID( rclsid, &CLSID_SAXXMLReader60 ))
259     {
260         cf = (IClassFactory*) &saxreadcf.lpVtbl;
261     }
262     else if( IsEqualCLSID( rclsid, &CLSID_XMLHTTPRequest ) ||
263              IsEqualCLSID( rclsid, &CLSID_XMLHTTP26 ) ||
264              IsEqualCLSID( rclsid, &CLSID_XMLHTTP30 ) ||
265              IsEqualCLSID( rclsid, &CLSID_XMLHTTP40 ) ||
266              IsEqualCLSID( rclsid, &CLSID_XMLHTTP60 ))
267     {
268         cf = (IClassFactory*) &httpreqcf.lpVtbl;
269     }
270     else if( IsEqualCLSID( rclsid, &CLSID_XSLTemplate )   ||
271              IsEqualCLSID( rclsid, &CLSID_XSLTemplate26 ) ||
272              IsEqualCLSID( rclsid, &CLSID_XSLTemplate30 ) ||
273              IsEqualCLSID( rclsid, &CLSID_XSLTemplate40 ) ||
274              IsEqualCLSID( rclsid, &CLSID_XSLTemplate60 ))
275     {
276         cf = (IClassFactory*) &xsltemplatecf.lpVtbl;
277     }
278
279     if ( !cf )
280         return CLASS_E_CLASSNOTAVAILABLE;
281
282     return IClassFactory_QueryInterface( cf, riid, ppv );
283 }