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