wbemprox: Implement IEnumWbemClassObject::Clone.
[wine] / dlls / wbemprox / services.c
1 /*
2  * Copyright 2012 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20
21 #include "config.h"
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "initguid.h"
27 #include "objbase.h"
28 #include "wbemcli.h"
29
30 #include "wine/debug.h"
31 #include "wine/unicode.h"
32 #include "wbemprox_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
35
36 struct client_security
37 {
38     IClientSecurity IClientSecurity_iface;
39 };
40
41 static inline struct client_security *impl_from_IClientSecurity( IClientSecurity *iface )
42 {
43     return CONTAINING_RECORD( iface, struct client_security, IClientSecurity_iface );
44 }
45
46 static HRESULT WINAPI client_security_QueryInterface(
47     IClientSecurity *iface,
48     REFIID riid,
49     void **ppvObject )
50 {
51     struct client_security *cs = impl_from_IClientSecurity( iface );
52
53     TRACE("%p %s %p\n", cs, debugstr_guid( riid ), ppvObject );
54
55     if ( IsEqualGUID( riid, &IID_IClientSecurity ) ||
56          IsEqualGUID( riid, &IID_IUnknown ) )
57     {
58         *ppvObject = cs;
59     }
60     else
61     {
62         FIXME("interface %s not implemented\n", debugstr_guid(riid));
63         return E_NOINTERFACE;
64     }
65     IClientSecurity_AddRef( iface );
66     return S_OK;
67 }
68
69 static ULONG WINAPI client_security_AddRef(
70     IClientSecurity *iface )
71 {
72     FIXME("%p\n", iface);
73     return 2;
74 }
75
76 static ULONG WINAPI client_security_Release(
77     IClientSecurity *iface )
78 {
79     FIXME("%p\n", iface);
80     return 1;
81 }
82
83 static HRESULT WINAPI client_security_QueryBlanket(
84     IClientSecurity *iface,
85     IUnknown *pProxy,
86     DWORD *pAuthnSvc,
87     DWORD *pAuthzSvc,
88     OLECHAR **pServerPrincName,
89     DWORD *pAuthnLevel,
90     DWORD *pImpLevel,
91     void **pAuthInfo,
92     DWORD *pCapabilities )
93 {
94     FIXME("\n");
95     return WBEM_E_FAILED;
96 }
97
98 static HRESULT WINAPI client_security_SetBlanket(
99     IClientSecurity *iface,
100     IUnknown *pProxy,
101     DWORD AuthnSvc,
102     DWORD AuthzSvc,
103     OLECHAR *pServerPrincName,
104     DWORD AuthnLevel,
105     DWORD ImpLevel,
106     void *pAuthInfo,
107     DWORD Capabilities )
108 {
109     FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc,
110           debugstr_w(pServerPrincName), AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
111     return WBEM_NO_ERROR;
112 }
113
114 static HRESULT WINAPI client_security_CopyProxy(
115     IClientSecurity *iface,
116     IUnknown *pProxy,
117     IUnknown **ppCopy )
118 {
119     FIXME("\n");
120     return WBEM_E_FAILED;
121 }
122
123 static const IClientSecurityVtbl client_security_vtbl =
124 {
125     client_security_QueryInterface,
126     client_security_AddRef,
127     client_security_Release,
128     client_security_QueryBlanket,
129     client_security_SetBlanket,
130     client_security_CopyProxy
131 };
132
133 IClientSecurity client_security = { &client_security_vtbl };
134
135 struct wbem_services
136 {
137     IWbemServices IWbemServices_iface;
138     LONG refs;
139     WCHAR *namespace;
140 };
141
142 static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
143 {
144     return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface );
145 }
146
147 static ULONG WINAPI wbem_services_AddRef(
148     IWbemServices *iface )
149 {
150     struct wbem_services *ws = impl_from_IWbemServices( iface );
151     return InterlockedIncrement( &ws->refs );
152 }
153
154 static ULONG WINAPI wbem_services_Release(
155     IWbemServices *iface )
156 {
157     struct wbem_services *ws = impl_from_IWbemServices( iface );
158     LONG refs = InterlockedDecrement( &ws->refs );
159     if (!refs)
160     {
161         TRACE("destroying %p\n", ws);
162         heap_free( ws->namespace );
163         heap_free( ws );
164     }
165     return refs;
166 }
167
168 static HRESULT WINAPI wbem_services_QueryInterface(
169     IWbemServices *iface,
170     REFIID riid,
171     void **ppvObject )
172 {
173     struct wbem_services *ws = impl_from_IWbemServices( iface );
174
175     TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject );
176
177     if ( IsEqualGUID( riid, &IID_IWbemServices ) ||
178          IsEqualGUID( riid, &IID_IUnknown ) )
179     {
180         *ppvObject = ws;
181     }
182     else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
183     {
184         *ppvObject = &client_security;
185         return S_OK;
186     }
187     else
188     {
189         FIXME("interface %s not implemented\n", debugstr_guid(riid));
190         return E_NOINTERFACE;
191     }
192     IWbemServices_AddRef( iface );
193     return S_OK;
194 }
195
196 static HRESULT WINAPI wbem_services_OpenNamespace(
197     IWbemServices *iface,
198     const BSTR strNamespace,
199     LONG lFlags,
200     IWbemContext *pCtx,
201     IWbemServices **ppWorkingNamespace,
202     IWbemCallResult **ppResult )
203 {
204     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
205     static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
206     struct wbem_services *ws = impl_from_IWbemServices( iface );
207
208     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
209           pCtx, ppWorkingNamespace, ppResult);
210
211     if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace)
212         return WBEM_E_INVALID_NAMESPACE;
213
214     return WbemServices_create( NULL, cimv2W, (void **)ppWorkingNamespace );
215 }
216
217 static HRESULT WINAPI wbem_services_CancelAsyncCall(
218     IWbemServices *iface,
219     IWbemObjectSink *pSink )
220 {
221     FIXME("\n");
222     return WBEM_E_FAILED;
223 }
224
225 static HRESULT WINAPI wbem_services_QueryObjectSink(
226     IWbemServices *iface,
227     LONG lFlags,
228     IWbemObjectSink **ppResponseHandler )
229 {
230     FIXME("\n");
231     return WBEM_E_FAILED;
232 }
233
234 static HRESULT WINAPI wbem_services_GetObject(
235     IWbemServices *iface,
236     const BSTR strObjectPath,
237     LONG lFlags,
238     IWbemContext *pCtx,
239     IWbemClassObject **ppObject,
240     IWbemCallResult **ppCallResult )
241 {
242     static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
243     IEnumWbemClassObject *iter;
244     WCHAR *query;
245     HRESULT hr;
246
247     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
248           pCtx, ppObject, ppCallResult);
249
250     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
251
252     /* FIXME: parse path */
253
254     if (!(query = heap_alloc( strlenW( strObjectPath ) * sizeof(WCHAR) + sizeof(selectW) )))
255         return E_OUTOFMEMORY;
256     strcpyW( query, selectW );
257     strcatW( query, strObjectPath );
258
259     hr = exec_query( query, &iter );
260     heap_free( query );
261     if (hr != S_OK) return hr;
262
263     hr = WbemClassObject_create( NULL, iter, 0, (void **)ppObject );
264     IEnumWbemClassObject_Release( iter );
265     return hr;
266 }
267
268 static HRESULT WINAPI wbem_services_GetObjectAsync(
269     IWbemServices *iface,
270     const BSTR strObjectPath,
271     LONG lFlags,
272     IWbemContext *pCtx,
273     IWbemObjectSink *pResponseHandler )
274 {
275     FIXME("\n");
276     return WBEM_E_FAILED;
277 }
278
279 static HRESULT WINAPI wbem_services_PutClass(
280     IWbemServices *iface,
281     IWbemClassObject *pObject,
282     LONG lFlags,
283     IWbemContext *pCtx,
284     IWbemCallResult **ppCallResult )
285 {
286     FIXME("\n");
287     return WBEM_E_FAILED;
288 }
289
290 static HRESULT WINAPI wbem_services_PutClassAsync(
291     IWbemServices *iface,
292     IWbemClassObject *pObject,
293     LONG lFlags,
294     IWbemContext *pCtx,
295     IWbemObjectSink *pResponseHandler )
296 {
297     FIXME("\n");
298     return WBEM_E_FAILED;
299 }
300
301 static HRESULT WINAPI wbem_services_DeleteClass(
302     IWbemServices *iface,
303     const BSTR strClass,
304     LONG lFlags,
305     IWbemContext *pCtx,
306     IWbemCallResult **ppCallResult )
307 {
308     FIXME("\n");
309     return WBEM_E_FAILED;
310 }
311
312 static HRESULT WINAPI wbem_services_DeleteClassAsync(
313     IWbemServices *iface,
314     const BSTR strClass,
315     LONG lFlags,
316     IWbemContext *pCtx,
317     IWbemObjectSink *pResponseHandler )
318 {
319     FIXME("\n");
320     return WBEM_E_FAILED;
321 }
322
323 static HRESULT WINAPI wbem_services_CreateClassEnum(
324     IWbemServices *iface,
325     const BSTR strSuperclass,
326     LONG lFlags,
327     IWbemContext *pCtx,
328     IEnumWbemClassObject **ppEnum )
329 {
330     FIXME("\n");
331     return WBEM_E_FAILED;
332 }
333
334 static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
335     IWbemServices *iface,
336     const BSTR strSuperclass,
337     LONG lFlags,
338     IWbemContext *pCtx,
339     IWbemObjectSink *pResponseHandler )
340 {
341     FIXME("\n");
342     return WBEM_E_FAILED;
343 }
344
345 static HRESULT WINAPI wbem_services_PutInstance(
346     IWbemServices *iface,
347     IWbemClassObject *pInst,
348     LONG lFlags,
349     IWbemContext *pCtx,
350     IWbemCallResult **ppCallResult )
351 {
352     FIXME("\n");
353     return WBEM_E_FAILED;
354 }
355
356 static HRESULT WINAPI wbem_services_PutInstanceAsync(
357     IWbemServices *iface,
358     IWbemClassObject *pInst,
359     LONG lFlags,
360     IWbemContext *pCtx,
361     IWbemObjectSink *pResponseHandler )
362 {
363     FIXME("\n");
364     return WBEM_E_FAILED;
365 }
366
367 static HRESULT WINAPI wbem_services_DeleteInstance(
368     IWbemServices *iface,
369     const BSTR strObjectPath,
370     LONG lFlags,
371     IWbemContext *pCtx,
372     IWbemCallResult **ppCallResult )
373 {
374     FIXME("\n");
375     return WBEM_E_FAILED;
376 }
377
378 static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
379     IWbemServices *iface,
380     const BSTR strObjectPath,
381     LONG lFlags,
382     IWbemContext *pCtx,
383     IWbemObjectSink *pResponseHandler )
384 {
385     FIXME("\n");
386     return WBEM_E_FAILED;
387 }
388
389 static HRESULT WINAPI wbem_services_CreateInstanceEnum(
390     IWbemServices *iface,
391     const BSTR strClass,
392     LONG lFlags,
393     IWbemContext *pCtx,
394     IEnumWbemClassObject **ppEnum )
395 {
396     static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
397     WCHAR *query;
398     HRESULT hr;
399
400     TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
401
402     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
403
404     if (!(query = heap_alloc( strlenW( strClass ) * sizeof(WCHAR) + sizeof(selectW) )))
405         return E_OUTOFMEMORY;
406     strcpyW( query, selectW );
407     strcatW( query, strClass );
408
409     hr = exec_query( query, ppEnum );
410     heap_free( query );
411     return hr;
412 }
413
414 static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
415     IWbemServices *iface,
416     const BSTR strFilter,
417     LONG lFlags,
418     IWbemContext *pCtx,
419     IWbemObjectSink *pResponseHandler )
420 {
421     FIXME("\n");
422     return WBEM_E_FAILED;
423 }
424
425 static HRESULT WINAPI wbem_services_ExecQuery(
426     IWbemServices *iface,
427     const BSTR strQueryLanguage,
428     const BSTR strQuery,
429     LONG lFlags,
430     IWbemContext *pCtx,
431     IEnumWbemClassObject **ppEnum )
432 {
433     static const WCHAR wqlW[] = {'W','Q','L',0};
434
435     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
436           debugstr_w(strQuery), lFlags, pCtx, ppEnum);
437
438     if (!strQueryLanguage || !strQuery) return WBEM_E_INVALID_PARAMETER;
439     if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
440     return exec_query( strQuery, ppEnum );
441 }
442
443 static HRESULT WINAPI wbem_services_ExecQueryAsync(
444     IWbemServices *iface,
445     const BSTR strQueryLanguage,
446     const BSTR strQuery,
447     LONG lFlags,
448     IWbemContext *pCtx,
449     IWbemObjectSink *pResponseHandler )
450 {
451     FIXME("\n");
452     return WBEM_E_FAILED;
453 }
454
455 static HRESULT WINAPI wbem_services_ExecNotificationQuery(
456     IWbemServices *iface,
457     const BSTR strQueryLanguage,
458     const BSTR strQuery,
459     LONG lFlags,
460     IWbemContext *pCtx,
461     IEnumWbemClassObject **ppEnum )
462 {
463     FIXME("\n");
464     return WBEM_E_FAILED;
465 }
466
467 static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
468     IWbemServices *iface,
469     const BSTR strQueryLanguage,
470     const BSTR strQuery,
471     LONG lFlags,
472     IWbemContext *pCtx,
473     IWbemObjectSink *pResponseHandler )
474 {
475     FIXME("\n");
476     return WBEM_E_FAILED;
477 }
478
479 static HRESULT WINAPI wbem_services_ExecMethod(
480     IWbemServices *iface,
481     const BSTR strObjectPath,
482     const BSTR strMethodName,
483     LONG lFlags,
484     IWbemContext *pCtx,
485     IWbemClassObject *pInParams,
486     IWbemClassObject **ppOutParams,
487     IWbemCallResult **ppCallResult )
488 {
489     FIXME("\n");
490     return WBEM_E_FAILED;
491 }
492
493 static HRESULT WINAPI wbem_services_ExecMethodAsync(
494     IWbemServices *iface,
495     const BSTR strObjectPath,
496     const BSTR strMethodName,
497     LONG lFlags,
498     IWbemContext *pCtx,
499     IWbemClassObject *pInParams,
500     IWbemObjectSink *pResponseHandler )
501 {
502     FIXME("\n");
503     return WBEM_E_FAILED;
504 }
505
506 static const IWbemServicesVtbl wbem_services_vtbl =
507 {
508     wbem_services_QueryInterface,
509     wbem_services_AddRef,
510     wbem_services_Release,
511     wbem_services_OpenNamespace,
512     wbem_services_CancelAsyncCall,
513     wbem_services_QueryObjectSink,
514     wbem_services_GetObject,
515     wbem_services_GetObjectAsync,
516     wbem_services_PutClass,
517     wbem_services_PutClassAsync,
518     wbem_services_DeleteClass,
519     wbem_services_DeleteClassAsync,
520     wbem_services_CreateClassEnum,
521     wbem_services_CreateClassEnumAsync,
522     wbem_services_PutInstance,
523     wbem_services_PutInstanceAsync,
524     wbem_services_DeleteInstance,
525     wbem_services_DeleteInstanceAsync,
526     wbem_services_CreateInstanceEnum,
527     wbem_services_CreateInstanceEnumAsync,
528     wbem_services_ExecQuery,
529     wbem_services_ExecQueryAsync,
530     wbem_services_ExecNotificationQuery,
531     wbem_services_ExecNotificationQueryAsync,
532     wbem_services_ExecMethod,
533     wbem_services_ExecMethodAsync
534 };
535
536 HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID *ppObj )
537 {
538     struct wbem_services *ws;
539
540     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
541
542     ws = heap_alloc( sizeof(*ws) );
543     if (!ws) return E_OUTOFMEMORY;
544
545     ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
546     ws->refs = 1;
547     ws->namespace = heap_strdupW( namespace );
548
549     *ppObj = &ws->IWbemServices_iface;
550
551     TRACE("returning iface %p\n", *ppObj);
552     return S_OK;
553 }