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