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