wbemprox: Add helpers for retrieving class instances.
[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     static const OLECHAR defaultW[] =
110         {'<','C','O','L','E','_','D','E','F','A','U','L','T','_','P','R','I','N','C','I','P','A','L','>',0};
111     const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ? defaultW : pServerPrincName;
112
113     FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc,
114           debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
115     return WBEM_NO_ERROR;
116 }
117
118 static HRESULT WINAPI client_security_CopyProxy(
119     IClientSecurity *iface,
120     IUnknown *pProxy,
121     IUnknown **ppCopy )
122 {
123     FIXME("\n");
124     return WBEM_E_FAILED;
125 }
126
127 static const IClientSecurityVtbl client_security_vtbl =
128 {
129     client_security_QueryInterface,
130     client_security_AddRef,
131     client_security_Release,
132     client_security_QueryBlanket,
133     client_security_SetBlanket,
134     client_security_CopyProxy
135 };
136
137 IClientSecurity client_security = { &client_security_vtbl };
138
139 struct wbem_services
140 {
141     IWbemServices IWbemServices_iface;
142     LONG refs;
143     WCHAR *namespace;
144 };
145
146 static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
147 {
148     return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface );
149 }
150
151 static ULONG WINAPI wbem_services_AddRef(
152     IWbemServices *iface )
153 {
154     struct wbem_services *ws = impl_from_IWbemServices( iface );
155     return InterlockedIncrement( &ws->refs );
156 }
157
158 static ULONG WINAPI wbem_services_Release(
159     IWbemServices *iface )
160 {
161     struct wbem_services *ws = impl_from_IWbemServices( iface );
162     LONG refs = InterlockedDecrement( &ws->refs );
163     if (!refs)
164     {
165         TRACE("destroying %p\n", ws);
166         heap_free( ws->namespace );
167         heap_free( ws );
168     }
169     return refs;
170 }
171
172 static HRESULT WINAPI wbem_services_QueryInterface(
173     IWbemServices *iface,
174     REFIID riid,
175     void **ppvObject )
176 {
177     struct wbem_services *ws = impl_from_IWbemServices( iface );
178
179     TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject );
180
181     if ( IsEqualGUID( riid, &IID_IWbemServices ) ||
182          IsEqualGUID( riid, &IID_IUnknown ) )
183     {
184         *ppvObject = ws;
185     }
186     else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
187     {
188         *ppvObject = &client_security;
189         return S_OK;
190     }
191     else
192     {
193         FIXME("interface %s not implemented\n", debugstr_guid(riid));
194         return E_NOINTERFACE;
195     }
196     IWbemServices_AddRef( iface );
197     return S_OK;
198 }
199
200 static HRESULT WINAPI wbem_services_OpenNamespace(
201     IWbemServices *iface,
202     const BSTR strNamespace,
203     LONG lFlags,
204     IWbemContext *pCtx,
205     IWbemServices **ppWorkingNamespace,
206     IWbemCallResult **ppResult )
207 {
208     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
209     static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
210     struct wbem_services *ws = impl_from_IWbemServices( iface );
211
212     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
213           pCtx, ppWorkingNamespace, ppResult);
214
215     if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace)
216         return WBEM_E_INVALID_NAMESPACE;
217
218     return WbemServices_create( NULL, cimv2W, (void **)ppWorkingNamespace );
219 }
220
221 static HRESULT WINAPI wbem_services_CancelAsyncCall(
222     IWbemServices *iface,
223     IWbemObjectSink *pSink )
224 {
225     FIXME("\n");
226     return WBEM_E_FAILED;
227 }
228
229 static HRESULT WINAPI wbem_services_QueryObjectSink(
230     IWbemServices *iface,
231     LONG lFlags,
232     IWbemObjectSink **ppResponseHandler )
233 {
234     FIXME("\n");
235     return WBEM_E_FAILED;
236 }
237
238 static HRESULT create_instance_enum( const WCHAR *class, IEnumWbemClassObject **iter )
239 {
240     static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
241     WCHAR *query;
242     HRESULT hr;
243
244     query = heap_alloc( strlenW( class ) * sizeof(WCHAR) + sizeof(selectW) );
245     if (!query) return E_OUTOFMEMORY;
246
247     strcpyW( query, selectW );
248     strcatW( query, class );
249
250     hr = exec_query( query, iter );
251     heap_free( query );
252     return hr;
253 }
254
255 HRESULT get_object( const WCHAR *path, IWbemClassObject **obj )
256 {
257     IEnumWbemClassObject *iter;
258     HRESULT hr;
259
260     /* FIXME: parse path */
261
262     hr = create_instance_enum( path, &iter );
263     if (hr != S_OK) return hr;
264
265     hr = WbemClassObject_create( NULL, iter, 0, (void **)obj );
266     IEnumWbemClassObject_Release( iter );
267     return hr;
268 }
269
270 static HRESULT WINAPI wbem_services_GetObject(
271     IWbemServices *iface,
272     const BSTR strObjectPath,
273     LONG lFlags,
274     IWbemContext *pCtx,
275     IWbemClassObject **ppObject,
276     IWbemCallResult **ppCallResult )
277 {
278     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
279           pCtx, ppObject, ppCallResult);
280
281     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
282
283     return get_object( strObjectPath, ppObject );
284 }
285
286 static HRESULT WINAPI wbem_services_GetObjectAsync(
287     IWbemServices *iface,
288     const BSTR strObjectPath,
289     LONG lFlags,
290     IWbemContext *pCtx,
291     IWbemObjectSink *pResponseHandler )
292 {
293     FIXME("\n");
294     return WBEM_E_FAILED;
295 }
296
297 static HRESULT WINAPI wbem_services_PutClass(
298     IWbemServices *iface,
299     IWbemClassObject *pObject,
300     LONG lFlags,
301     IWbemContext *pCtx,
302     IWbemCallResult **ppCallResult )
303 {
304     FIXME("\n");
305     return WBEM_E_FAILED;
306 }
307
308 static HRESULT WINAPI wbem_services_PutClassAsync(
309     IWbemServices *iface,
310     IWbemClassObject *pObject,
311     LONG lFlags,
312     IWbemContext *pCtx,
313     IWbemObjectSink *pResponseHandler )
314 {
315     FIXME("\n");
316     return WBEM_E_FAILED;
317 }
318
319 static HRESULT WINAPI wbem_services_DeleteClass(
320     IWbemServices *iface,
321     const BSTR strClass,
322     LONG lFlags,
323     IWbemContext *pCtx,
324     IWbemCallResult **ppCallResult )
325 {
326     FIXME("\n");
327     return WBEM_E_FAILED;
328 }
329
330 static HRESULT WINAPI wbem_services_DeleteClassAsync(
331     IWbemServices *iface,
332     const BSTR strClass,
333     LONG lFlags,
334     IWbemContext *pCtx,
335     IWbemObjectSink *pResponseHandler )
336 {
337     FIXME("\n");
338     return WBEM_E_FAILED;
339 }
340
341 static HRESULT WINAPI wbem_services_CreateClassEnum(
342     IWbemServices *iface,
343     const BSTR strSuperclass,
344     LONG lFlags,
345     IWbemContext *pCtx,
346     IEnumWbemClassObject **ppEnum )
347 {
348     FIXME("\n");
349     return WBEM_E_FAILED;
350 }
351
352 static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
353     IWbemServices *iface,
354     const BSTR strSuperclass,
355     LONG lFlags,
356     IWbemContext *pCtx,
357     IWbemObjectSink *pResponseHandler )
358 {
359     FIXME("\n");
360     return WBEM_E_FAILED;
361 }
362
363 static HRESULT WINAPI wbem_services_PutInstance(
364     IWbemServices *iface,
365     IWbemClassObject *pInst,
366     LONG lFlags,
367     IWbemContext *pCtx,
368     IWbemCallResult **ppCallResult )
369 {
370     FIXME("\n");
371     return WBEM_E_FAILED;
372 }
373
374 static HRESULT WINAPI wbem_services_PutInstanceAsync(
375     IWbemServices *iface,
376     IWbemClassObject *pInst,
377     LONG lFlags,
378     IWbemContext *pCtx,
379     IWbemObjectSink *pResponseHandler )
380 {
381     FIXME("\n");
382     return WBEM_E_FAILED;
383 }
384
385 static HRESULT WINAPI wbem_services_DeleteInstance(
386     IWbemServices *iface,
387     const BSTR strObjectPath,
388     LONG lFlags,
389     IWbemContext *pCtx,
390     IWbemCallResult **ppCallResult )
391 {
392     FIXME("\n");
393     return WBEM_E_FAILED;
394 }
395
396 static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
397     IWbemServices *iface,
398     const BSTR strObjectPath,
399     LONG lFlags,
400     IWbemContext *pCtx,
401     IWbemObjectSink *pResponseHandler )
402 {
403     FIXME("\n");
404     return WBEM_E_FAILED;
405 }
406
407 static HRESULT WINAPI wbem_services_CreateInstanceEnum(
408     IWbemServices *iface,
409     const BSTR strClass,
410     LONG lFlags,
411     IWbemContext *pCtx,
412     IEnumWbemClassObject **ppEnum )
413 {
414     TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
415
416     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
417
418     return create_instance_enum( strClass, ppEnum );
419 }
420
421 static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
422     IWbemServices *iface,
423     const BSTR strFilter,
424     LONG lFlags,
425     IWbemContext *pCtx,
426     IWbemObjectSink *pResponseHandler )
427 {
428     FIXME("\n");
429     return WBEM_E_FAILED;
430 }
431
432 static HRESULT WINAPI wbem_services_ExecQuery(
433     IWbemServices *iface,
434     const BSTR strQueryLanguage,
435     const BSTR strQuery,
436     LONG lFlags,
437     IWbemContext *pCtx,
438     IEnumWbemClassObject **ppEnum )
439 {
440     static const WCHAR wqlW[] = {'W','Q','L',0};
441
442     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
443           debugstr_w(strQuery), lFlags, pCtx, ppEnum);
444
445     if (!strQueryLanguage || !strQuery) return WBEM_E_INVALID_PARAMETER;
446     if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
447     return exec_query( strQuery, ppEnum );
448 }
449
450 static HRESULT WINAPI wbem_services_ExecQueryAsync(
451     IWbemServices *iface,
452     const BSTR strQueryLanguage,
453     const BSTR strQuery,
454     LONG lFlags,
455     IWbemContext *pCtx,
456     IWbemObjectSink *pResponseHandler )
457 {
458     FIXME("\n");
459     return WBEM_E_FAILED;
460 }
461
462 static HRESULT WINAPI wbem_services_ExecNotificationQuery(
463     IWbemServices *iface,
464     const BSTR strQueryLanguage,
465     const BSTR strQuery,
466     LONG lFlags,
467     IWbemContext *pCtx,
468     IEnumWbemClassObject **ppEnum )
469 {
470     FIXME("\n");
471     return WBEM_E_FAILED;
472 }
473
474 static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
475     IWbemServices *iface,
476     const BSTR strQueryLanguage,
477     const BSTR strQuery,
478     LONG lFlags,
479     IWbemContext *pCtx,
480     IWbemObjectSink *pResponseHandler )
481 {
482     FIXME("\n");
483     return WBEM_E_FAILED;
484 }
485
486 static HRESULT WINAPI wbem_services_ExecMethod(
487     IWbemServices *iface,
488     const BSTR strObjectPath,
489     const BSTR strMethodName,
490     LONG lFlags,
491     IWbemContext *pCtx,
492     IWbemClassObject *pInParams,
493     IWbemClassObject **ppOutParams,
494     IWbemCallResult **ppCallResult )
495 {
496     FIXME("\n");
497     return WBEM_E_FAILED;
498 }
499
500 static HRESULT WINAPI wbem_services_ExecMethodAsync(
501     IWbemServices *iface,
502     const BSTR strObjectPath,
503     const BSTR strMethodName,
504     LONG lFlags,
505     IWbemContext *pCtx,
506     IWbemClassObject *pInParams,
507     IWbemObjectSink *pResponseHandler )
508 {
509     FIXME("\n");
510     return WBEM_E_FAILED;
511 }
512
513 static const IWbemServicesVtbl wbem_services_vtbl =
514 {
515     wbem_services_QueryInterface,
516     wbem_services_AddRef,
517     wbem_services_Release,
518     wbem_services_OpenNamespace,
519     wbem_services_CancelAsyncCall,
520     wbem_services_QueryObjectSink,
521     wbem_services_GetObject,
522     wbem_services_GetObjectAsync,
523     wbem_services_PutClass,
524     wbem_services_PutClassAsync,
525     wbem_services_DeleteClass,
526     wbem_services_DeleteClassAsync,
527     wbem_services_CreateClassEnum,
528     wbem_services_CreateClassEnumAsync,
529     wbem_services_PutInstance,
530     wbem_services_PutInstanceAsync,
531     wbem_services_DeleteInstance,
532     wbem_services_DeleteInstanceAsync,
533     wbem_services_CreateInstanceEnum,
534     wbem_services_CreateInstanceEnumAsync,
535     wbem_services_ExecQuery,
536     wbem_services_ExecQueryAsync,
537     wbem_services_ExecNotificationQuery,
538     wbem_services_ExecNotificationQueryAsync,
539     wbem_services_ExecMethod,
540     wbem_services_ExecMethodAsync
541 };
542
543 HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID *ppObj )
544 {
545     struct wbem_services *ws;
546
547     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
548
549     ws = heap_alloc( sizeof(*ws) );
550     if (!ws) return E_OUTOFMEMORY;
551
552     ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
553     ws->refs = 1;
554     ws->namespace = heap_strdupW( namespace );
555
556     *ppObj = &ws->IWbemServices_iface;
557
558     TRACE("returning iface %p\n", *ppObj);
559     return S_OK;
560 }