wbemprox: Store the class name in the class object.
[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 struct path
239 {
240     WCHAR *class;
241     UINT   class_len;
242     WCHAR *filter;
243     UINT   filter_len;
244 };
245
246 static HRESULT parse_path( const WCHAR *str, struct path **ret )
247 {
248     struct path *path;
249     const WCHAR *p = str, *q;
250     UINT len;
251
252     if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY;
253
254     while (*p && *p != '.') p++;
255
256     len = p - str;
257     if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) )))
258     {
259         heap_free( path );
260         return E_OUTOFMEMORY;
261     }
262     memcpy( path->class, str, len * sizeof(WCHAR) );
263     path->class[len] = 0;
264     path->class_len = len;
265
266     if (p[0] == '.' && p[1])
267     {
268         q = ++p;
269         while (*q) q++;
270
271         len = q - p;
272         if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) )))
273         {
274             heap_free( path->class );
275             heap_free( path );
276             return E_OUTOFMEMORY;
277         }
278         memcpy( path->filter, p, len * sizeof(WCHAR) );
279         path->filter[len] = 0;
280         path->filter_len = len;
281     }
282     *ret = path;
283     return S_OK;
284 }
285
286 static void free_path( struct path *path )
287 {
288     heap_free( path->class );
289     heap_free( path->filter );
290     heap_free( path );
291 }
292
293 static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter )
294 {
295     static const WCHAR selectW[] =
296         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ',
297          'W','H','E','R','E',' ','%','s',0};
298     static const WCHAR select_allW[] =
299         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
300     WCHAR *query;
301     HRESULT hr;
302     UINT len;
303
304     if (path->filter)
305     {
306         len = path->class_len + path->filter_len + SIZEOF(selectW);
307         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
308         sprintfW( query, selectW, path->class, path->filter );
309     }
310     else
311     {
312         len = path->class_len + SIZEOF(select_allW);
313         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
314         strcpyW( query, select_allW );
315         strcatW( query, path->class );
316     }
317     hr = exec_query( query, iter );
318     heap_free( query );
319     return hr;
320 }
321
322 HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj )
323 {
324     IEnumWbemClassObject *iter;
325     struct path *path;
326     HRESULT hr;
327
328     hr = parse_path( object_path, &path );
329     if (hr != S_OK) return hr;
330
331     hr = create_instance_enum( path, &iter );
332     if (hr != S_OK)
333     {
334         free_path( path );
335         return hr;
336     }
337     hr = create_class_object( path->class, iter, 0, obj );
338     IEnumWbemClassObject_Release( iter );
339     free_path( path );
340     return hr;
341 }
342
343 static HRESULT WINAPI wbem_services_GetObject(
344     IWbemServices *iface,
345     const BSTR strObjectPath,
346     LONG lFlags,
347     IWbemContext *pCtx,
348     IWbemClassObject **ppObject,
349     IWbemCallResult **ppCallResult )
350 {
351     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
352           pCtx, ppObject, ppCallResult);
353
354     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
355
356     if (!strObjectPath)
357     {
358         FIXME("no support for creating new classes\n");
359         return WBEM_E_FAILED;
360     }
361     return get_object( strObjectPath, ppObject );
362 }
363
364 static HRESULT WINAPI wbem_services_GetObjectAsync(
365     IWbemServices *iface,
366     const BSTR strObjectPath,
367     LONG lFlags,
368     IWbemContext *pCtx,
369     IWbemObjectSink *pResponseHandler )
370 {
371     FIXME("\n");
372     return WBEM_E_FAILED;
373 }
374
375 static HRESULT WINAPI wbem_services_PutClass(
376     IWbemServices *iface,
377     IWbemClassObject *pObject,
378     LONG lFlags,
379     IWbemContext *pCtx,
380     IWbemCallResult **ppCallResult )
381 {
382     FIXME("\n");
383     return WBEM_E_FAILED;
384 }
385
386 static HRESULT WINAPI wbem_services_PutClassAsync(
387     IWbemServices *iface,
388     IWbemClassObject *pObject,
389     LONG lFlags,
390     IWbemContext *pCtx,
391     IWbemObjectSink *pResponseHandler )
392 {
393     FIXME("\n");
394     return WBEM_E_FAILED;
395 }
396
397 static HRESULT WINAPI wbem_services_DeleteClass(
398     IWbemServices *iface,
399     const BSTR strClass,
400     LONG lFlags,
401     IWbemContext *pCtx,
402     IWbemCallResult **ppCallResult )
403 {
404     FIXME("\n");
405     return WBEM_E_FAILED;
406 }
407
408 static HRESULT WINAPI wbem_services_DeleteClassAsync(
409     IWbemServices *iface,
410     const BSTR strClass,
411     LONG lFlags,
412     IWbemContext *pCtx,
413     IWbemObjectSink *pResponseHandler )
414 {
415     FIXME("\n");
416     return WBEM_E_FAILED;
417 }
418
419 static HRESULT WINAPI wbem_services_CreateClassEnum(
420     IWbemServices *iface,
421     const BSTR strSuperclass,
422     LONG lFlags,
423     IWbemContext *pCtx,
424     IEnumWbemClassObject **ppEnum )
425 {
426     FIXME("\n");
427     return WBEM_E_FAILED;
428 }
429
430 static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
431     IWbemServices *iface,
432     const BSTR strSuperclass,
433     LONG lFlags,
434     IWbemContext *pCtx,
435     IWbemObjectSink *pResponseHandler )
436 {
437     FIXME("\n");
438     return WBEM_E_FAILED;
439 }
440
441 static HRESULT WINAPI wbem_services_PutInstance(
442     IWbemServices *iface,
443     IWbemClassObject *pInst,
444     LONG lFlags,
445     IWbemContext *pCtx,
446     IWbemCallResult **ppCallResult )
447 {
448     FIXME("\n");
449     return WBEM_E_FAILED;
450 }
451
452 static HRESULT WINAPI wbem_services_PutInstanceAsync(
453     IWbemServices *iface,
454     IWbemClassObject *pInst,
455     LONG lFlags,
456     IWbemContext *pCtx,
457     IWbemObjectSink *pResponseHandler )
458 {
459     FIXME("\n");
460     return WBEM_E_FAILED;
461 }
462
463 static HRESULT WINAPI wbem_services_DeleteInstance(
464     IWbemServices *iface,
465     const BSTR strObjectPath,
466     LONG lFlags,
467     IWbemContext *pCtx,
468     IWbemCallResult **ppCallResult )
469 {
470     FIXME("\n");
471     return WBEM_E_FAILED;
472 }
473
474 static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
475     IWbemServices *iface,
476     const BSTR strObjectPath,
477     LONG lFlags,
478     IWbemContext *pCtx,
479     IWbemObjectSink *pResponseHandler )
480 {
481     FIXME("\n");
482     return WBEM_E_FAILED;
483 }
484
485 static HRESULT WINAPI wbem_services_CreateInstanceEnum(
486     IWbemServices *iface,
487     const BSTR strClass,
488     LONG lFlags,
489     IWbemContext *pCtx,
490     IEnumWbemClassObject **ppEnum )
491 {
492     struct path *path;
493     HRESULT hr;
494
495     TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
496
497     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
498
499     hr = parse_path( strClass, &path );
500     if (hr != S_OK) return hr;
501
502     hr = create_instance_enum( path, ppEnum );
503     free_path( path );
504     return hr;
505 }
506
507 static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
508     IWbemServices *iface,
509     const BSTR strFilter,
510     LONG lFlags,
511     IWbemContext *pCtx,
512     IWbemObjectSink *pResponseHandler )
513 {
514     FIXME("\n");
515     return WBEM_E_FAILED;
516 }
517
518 static HRESULT WINAPI wbem_services_ExecQuery(
519     IWbemServices *iface,
520     const BSTR strQueryLanguage,
521     const BSTR strQuery,
522     LONG lFlags,
523     IWbemContext *pCtx,
524     IEnumWbemClassObject **ppEnum )
525 {
526     static const WCHAR wqlW[] = {'W','Q','L',0};
527
528     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
529           debugstr_w(strQuery), lFlags, pCtx, ppEnum);
530
531     if (!strQueryLanguage || !strQuery) return WBEM_E_INVALID_PARAMETER;
532     if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
533     return exec_query( strQuery, ppEnum );
534 }
535
536 static HRESULT WINAPI wbem_services_ExecQueryAsync(
537     IWbemServices *iface,
538     const BSTR strQueryLanguage,
539     const BSTR strQuery,
540     LONG lFlags,
541     IWbemContext *pCtx,
542     IWbemObjectSink *pResponseHandler )
543 {
544     FIXME("\n");
545     return WBEM_E_FAILED;
546 }
547
548 static HRESULT WINAPI wbem_services_ExecNotificationQuery(
549     IWbemServices *iface,
550     const BSTR strQueryLanguage,
551     const BSTR strQuery,
552     LONG lFlags,
553     IWbemContext *pCtx,
554     IEnumWbemClassObject **ppEnum )
555 {
556     FIXME("\n");
557     return WBEM_E_FAILED;
558 }
559
560 static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
561     IWbemServices *iface,
562     const BSTR strQueryLanguage,
563     const BSTR strQuery,
564     LONG lFlags,
565     IWbemContext *pCtx,
566     IWbemObjectSink *pResponseHandler )
567 {
568     FIXME("\n");
569     return WBEM_E_FAILED;
570 }
571
572 static HRESULT WINAPI wbem_services_ExecMethod(
573     IWbemServices *iface,
574     const BSTR strObjectPath,
575     const BSTR strMethodName,
576     LONG lFlags,
577     IWbemContext *pCtx,
578     IWbemClassObject *pInParams,
579     IWbemClassObject **ppOutParams,
580     IWbemCallResult **ppCallResult )
581 {
582     FIXME("\n");
583     return WBEM_E_FAILED;
584 }
585
586 static HRESULT WINAPI wbem_services_ExecMethodAsync(
587     IWbemServices *iface,
588     const BSTR strObjectPath,
589     const BSTR strMethodName,
590     LONG lFlags,
591     IWbemContext *pCtx,
592     IWbemClassObject *pInParams,
593     IWbemObjectSink *pResponseHandler )
594 {
595     FIXME("\n");
596     return WBEM_E_FAILED;
597 }
598
599 static const IWbemServicesVtbl wbem_services_vtbl =
600 {
601     wbem_services_QueryInterface,
602     wbem_services_AddRef,
603     wbem_services_Release,
604     wbem_services_OpenNamespace,
605     wbem_services_CancelAsyncCall,
606     wbem_services_QueryObjectSink,
607     wbem_services_GetObject,
608     wbem_services_GetObjectAsync,
609     wbem_services_PutClass,
610     wbem_services_PutClassAsync,
611     wbem_services_DeleteClass,
612     wbem_services_DeleteClassAsync,
613     wbem_services_CreateClassEnum,
614     wbem_services_CreateClassEnumAsync,
615     wbem_services_PutInstance,
616     wbem_services_PutInstanceAsync,
617     wbem_services_DeleteInstance,
618     wbem_services_DeleteInstanceAsync,
619     wbem_services_CreateInstanceEnum,
620     wbem_services_CreateInstanceEnumAsync,
621     wbem_services_ExecQuery,
622     wbem_services_ExecQueryAsync,
623     wbem_services_ExecNotificationQuery,
624     wbem_services_ExecNotificationQueryAsync,
625     wbem_services_ExecMethod,
626     wbem_services_ExecMethodAsync
627 };
628
629 HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID *ppObj )
630 {
631     struct wbem_services *ws;
632
633     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
634
635     ws = heap_alloc( sizeof(*ws) );
636     if (!ws) return E_OUTOFMEMORY;
637
638     ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
639     ws->refs = 1;
640     ws->namespace = heap_strdupW( namespace );
641
642     *ppObj = &ws->IWbemServices_iface;
643
644     TRACE("returning iface %p\n", *ppObj);
645     return S_OK;
646 }