xref: /reactos/dll/win32/wbemprox/qualifier.c (revision 628f4c99)
1 /*
2  * Copyright 2013 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 <stdarg.h>
22 #ifdef __REACTOS__
23 #include <wchar.h>
24 #endif
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "wbemcli.h"
30 
31 #include "wine/debug.h"
32 #include "wbemprox_private.h"
33 
34 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
35 
36 struct qualifier_set
37 {
38     IWbemQualifierSet IWbemQualifierSet_iface;
39     LONG refs;
40     WCHAR *class;
41     WCHAR *member;
42 };
43 
impl_from_IWbemQualifierSet(IWbemQualifierSet * iface)44 static inline struct qualifier_set *impl_from_IWbemQualifierSet(
45     IWbemQualifierSet *iface )
46 {
47     return CONTAINING_RECORD(iface, struct qualifier_set, IWbemQualifierSet_iface);
48 }
49 
qualifier_set_AddRef(IWbemQualifierSet * iface)50 static ULONG WINAPI qualifier_set_AddRef(
51     IWbemQualifierSet *iface )
52 {
53     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
54     return InterlockedIncrement( &set->refs );
55 }
56 
qualifier_set_Release(IWbemQualifierSet * iface)57 static ULONG WINAPI qualifier_set_Release(
58     IWbemQualifierSet *iface )
59 {
60     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
61     LONG refs = InterlockedDecrement( &set->refs );
62     if (!refs)
63     {
64         TRACE("destroying %p\n", set);
65         heap_free( set->class );
66         heap_free( set->member );
67         heap_free( set );
68     }
69     return refs;
70 }
71 
qualifier_set_QueryInterface(IWbemQualifierSet * iface,REFIID riid,void ** ppvObject)72 static HRESULT WINAPI qualifier_set_QueryInterface(
73     IWbemQualifierSet *iface,
74     REFIID riid,
75     void **ppvObject )
76 {
77     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
78 
79     TRACE("%p, %s, %p\n", set, debugstr_guid( riid ), ppvObject );
80 
81     if ( IsEqualGUID( riid, &IID_IWbemQualifierSet ) ||
82          IsEqualGUID( riid, &IID_IUnknown ) )
83     {
84         *ppvObject = set;
85     }
86     else
87     {
88         FIXME("interface %s not implemented\n", debugstr_guid(riid));
89         return E_NOINTERFACE;
90     }
91     IWbemQualifierSet_AddRef( iface );
92     return S_OK;
93 }
94 
create_qualifier_enum(const WCHAR * class,const WCHAR * member,const WCHAR * name,IEnumWbemClassObject ** iter)95 static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, const WCHAR *name,
96                                       IEnumWbemClassObject **iter )
97 {
98     static const WCHAR fmtW[] =
99         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L',
100          'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=',
101          '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',' ',
102          'A','N','D',' ','N','a','m','e','=','\'','%','s','\'',0};
103     static const WCHAR fmt2W[] =
104         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L',
105          'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=',
106          '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',0};
107     static const WCHAR fmt3W[] =
108         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L',
109          'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=',
110          '\'','%','s','\'',0};
111     WCHAR *query;
112     HRESULT hr;
113     int len;
114 
115     if (member && name)
116     {
117         len = lstrlenW( class ) + lstrlenW( member ) + lstrlenW( name ) + ARRAY_SIZE(fmtW);
118         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
119         swprintf( query, fmtW, class, member, name );
120     }
121     else if (member)
122     {
123         len = lstrlenW( class ) + lstrlenW( member ) + ARRAY_SIZE(fmt2W);
124         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
125         swprintf( query, fmt2W, class, member );
126     }
127     else
128     {
129         len = lstrlenW( class ) + ARRAY_SIZE(fmt3W);
130         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
131         swprintf( query, fmt3W, class );
132     }
133 
134     hr = exec_query( query, iter );
135     heap_free( query );
136     return hr;
137 }
138 
get_qualifier_value(const WCHAR * class,const WCHAR * member,const WCHAR * name,VARIANT * val,LONG * flavor)139 static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, const WCHAR *name,
140                                     VARIANT *val, LONG *flavor )
141 {
142     static const WCHAR intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0};
143     static const WCHAR strvalueW[] = {'S','t','r','i','n','g','V','a','l','u','e',0};
144     static const WCHAR boolvalueW[] = {'B','o','o','l','V','a','l','u','e',0};
145     static const WCHAR flavorW[] = {'F','l','a','v','o','r',0};
146     static const WCHAR typeW[] = {'T','y','p','e',0};
147     IEnumWbemClassObject *iter;
148     IWbemClassObject *obj;
149     VARIANT var;
150     HRESULT hr;
151 
152     hr = create_qualifier_enum( class, member, name, &iter );
153     if (FAILED( hr )) return hr;
154 
155     hr = create_class_object( NULL, iter, 0, NULL, &obj );
156     IEnumWbemClassObject_Release( iter );
157     if (FAILED( hr )) return hr;
158 
159     if (flavor)
160     {
161         hr = IWbemClassObject_Get( obj, flavorW, 0, &var, NULL, NULL );
162         if (hr != S_OK) goto done;
163         *flavor = V_I4( &var );
164     }
165     hr = IWbemClassObject_Get( obj, typeW, 0, &var, NULL, NULL );
166     if (hr != S_OK) goto done;
167     switch (V_UI4( &var ))
168     {
169     case CIM_STRING:
170         hr = IWbemClassObject_Get( obj, strvalueW, 0, val, NULL, NULL );
171         break;
172     case CIM_SINT32:
173         hr = IWbemClassObject_Get( obj, intvalueW, 0, val, NULL, NULL );
174         break;
175     case CIM_BOOLEAN:
176         hr = IWbemClassObject_Get( obj, boolvalueW, 0, val, NULL, NULL );
177         break;
178     default:
179         ERR("unhandled type %u\n", V_UI4( &var ));
180         break;
181     }
182 
183 done:
184     IWbemClassObject_Release( obj );
185     return hr;
186 }
187 
qualifier_set_Get(IWbemQualifierSet * iface,LPCWSTR wszName,LONG lFlags,VARIANT * pVal,LONG * plFlavor)188 static HRESULT WINAPI qualifier_set_Get(
189     IWbemQualifierSet *iface,
190     LPCWSTR wszName,
191     LONG lFlags,
192     VARIANT *pVal,
193     LONG *plFlavor )
194 {
195     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
196 
197     TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor);
198     if (lFlags)
199     {
200         FIXME("flags %08x not supported\n", lFlags);
201         return E_NOTIMPL;
202     }
203     return get_qualifier_value( set->class, set->member, wszName, pVal, plFlavor );
204 }
205 
qualifier_set_Put(IWbemQualifierSet * iface,LPCWSTR wszName,VARIANT * pVal,LONG lFlavor)206 static HRESULT WINAPI qualifier_set_Put(
207     IWbemQualifierSet *iface,
208     LPCWSTR wszName,
209     VARIANT *pVal,
210     LONG lFlavor )
211 {
212     FIXME("%p, %s, %p, %d\n", iface, debugstr_w(wszName), pVal, lFlavor);
213     return E_NOTIMPL;
214 }
215 
qualifier_set_Delete(IWbemQualifierSet * iface,LPCWSTR wszName)216 static HRESULT WINAPI qualifier_set_Delete(
217     IWbemQualifierSet *iface,
218     LPCWSTR wszName )
219 {
220     FIXME("%p, %s\n", iface, debugstr_w(wszName));
221     return E_NOTIMPL;
222 }
223 
qualifier_set_GetNames(IWbemQualifierSet * iface,LONG lFlags,SAFEARRAY ** pNames)224 static HRESULT WINAPI qualifier_set_GetNames(
225     IWbemQualifierSet *iface,
226     LONG lFlags,
227     SAFEARRAY **pNames )
228 {
229     struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
230     IEnumWbemClassObject *iter;
231     IWbemClassObject *obj;
232     HRESULT hr;
233 
234     TRACE("%p, %08x, %p\n", iface, lFlags, pNames);
235     if (lFlags)
236     {
237         FIXME("flags %08x not supported\n", lFlags);
238         return E_NOTIMPL;
239     }
240 
241     hr = create_qualifier_enum( set->class, set->member, NULL, &iter );
242     if (FAILED( hr )) return hr;
243 
244     hr = create_class_object( NULL, iter, 0, NULL, &obj );
245     IEnumWbemClassObject_Release( iter );
246     if (FAILED( hr )) return hr;
247 
248     hr = IWbemClassObject_GetNames( obj, NULL, 0, NULL, pNames );
249     IWbemClassObject_Release( obj );
250     return hr;
251 }
252 
qualifier_set_BeginEnumeration(IWbemQualifierSet * iface,LONG lFlags)253 static HRESULT WINAPI qualifier_set_BeginEnumeration(
254     IWbemQualifierSet *iface,
255     LONG lFlags )
256 {
257     FIXME("%p, %08x\n", iface, lFlags);
258     return E_NOTIMPL;
259 }
260 
qualifier_set_Next(IWbemQualifierSet * iface,LONG lFlags,BSTR * pstrName,VARIANT * pVal,LONG * plFlavor)261 static HRESULT WINAPI qualifier_set_Next(
262     IWbemQualifierSet *iface,
263     LONG lFlags,
264     BSTR *pstrName,
265     VARIANT *pVal,
266     LONG *plFlavor )
267 {
268     FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, pVal, plFlavor);
269     return E_NOTIMPL;
270 }
271 
qualifier_set_EndEnumeration(IWbemQualifierSet * iface)272 static HRESULT WINAPI qualifier_set_EndEnumeration(
273     IWbemQualifierSet *iface )
274 {
275     FIXME("%p\n", iface);
276     return E_NOTIMPL;
277 }
278 
279 static const IWbemQualifierSetVtbl qualifier_set_vtbl =
280 {
281     qualifier_set_QueryInterface,
282     qualifier_set_AddRef,
283     qualifier_set_Release,
284     qualifier_set_Get,
285     qualifier_set_Put,
286     qualifier_set_Delete,
287     qualifier_set_GetNames,
288     qualifier_set_BeginEnumeration,
289     qualifier_set_Next,
290     qualifier_set_EndEnumeration
291 };
292 
WbemQualifierSet_create(const WCHAR * class,const WCHAR * member,LPVOID * ppObj)293 HRESULT WbemQualifierSet_create( const WCHAR *class, const WCHAR *member, LPVOID *ppObj )
294 {
295     struct qualifier_set *set;
296 
297     TRACE("%p\n", ppObj);
298 
299     if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY;
300 
301     set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl;
302     if (!(set->class = heap_strdupW( class )))
303     {
304         heap_free( set );
305         return E_OUTOFMEMORY;
306     }
307     if (!member) set->member = NULL;
308     else if (!(set->member = heap_strdupW( member )))
309     {
310         heap_free( set->class );
311         heap_free( set );
312         return E_OUTOFMEMORY;
313     }
314     set->refs = 1;
315 
316     *ppObj = &set->IWbemQualifierSet_iface;
317 
318     TRACE("returning iface %p\n", *ppObj);
319     return S_OK;
320 }
321