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 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 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 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 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 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 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 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 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 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 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 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 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 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 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