[RSHELL]
[reactos.git] / dll / win32 / wbemprox / qualifier.c
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(
238 IUnknown *pUnkOuter, const WCHAR *class, const WCHAR *member, LPVOID *ppObj )
239 {
240 struct qualifier_set *set;
241
242 TRACE("%p, %p\n", pUnkOuter, ppObj);
243
244 if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY;
245
246 set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl;
247 if (!(set->class = heap_strdupW( class )))
248 {
249 heap_free( set );
250 return E_OUTOFMEMORY;
251 }
252 if (!member) set->member = NULL;
253 else if (!(set->member = heap_strdupW( member )))
254 {
255 heap_free( set->class );
256 heap_free( set );
257 return E_OUTOFMEMORY;
258 }
259 set->refs = 1;
260
261 *ppObj = &set->IWbemQualifierSet_iface;
262
263 TRACE("returning iface %p\n", *ppObj);
264 return S_OK;
265 }