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 ) + ARRAY_SIZE(fmtW); 113 else len += ARRAY_SIZE(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( const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) 251 { 252 struct qualifier_set *set; 253 254 TRACE("%p\n", ppObj); 255 256 if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; 257 258 set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl; 259 if (!(set->class = heap_strdupW( class ))) 260 { 261 heap_free( set ); 262 return E_OUTOFMEMORY; 263 } 264 if (!member) set->member = NULL; 265 else if (!(set->member = heap_strdupW( member ))) 266 { 267 heap_free( set->class ); 268 heap_free( set ); 269 return E_OUTOFMEMORY; 270 } 271 set->refs = 1; 272 273 *ppObj = &set->IWbemQualifierSet_iface; 274 275 TRACE("returning iface %p\n", *ppObj); 276 return S_OK; 277 } 278