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