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