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