2 * Copyright 2012 Hans Leidekker for CodeWeavers
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.
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.
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
29 #include "wine/debug.h"
30 #include "wbemprox_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
34 struct enum_class_object
36 IEnumWbemClassObject IEnumWbemClassObject_iface;
42 static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
43 IEnumWbemClassObject *iface )
45 return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
48 static ULONG WINAPI enum_class_object_AddRef(
49 IEnumWbemClassObject *iface )
51 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
52 return InterlockedIncrement( &ec->refs );
55 static ULONG WINAPI enum_class_object_Release(
56 IEnumWbemClassObject *iface )
58 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
59 LONG refs = InterlockedDecrement( &ec->refs );
62 TRACE("destroying %p\n", ec);
63 release_query( ec->query );
69 static HRESULT WINAPI enum_class_object_QueryInterface(
70 IEnumWbemClassObject *iface,
74 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
76 TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );
78 if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
79 IsEqualGUID( riid, &IID_IUnknown ) )
83 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
85 *ppvObject = &client_security;
90 FIXME("interface %s not implemented\n", debugstr_guid(riid));
93 IEnumWbemClassObject_AddRef( iface );
97 static HRESULT WINAPI enum_class_object_Reset(
98 IEnumWbemClassObject *iface )
100 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
102 TRACE("%p\n", iface);
105 return WBEM_S_NO_ERROR;
108 static HRESULT WINAPI enum_class_object_Next(
109 IEnumWbemClassObject *iface,
112 IWbemClassObject **apObjects,
115 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
116 struct view *view = ec->query->view;
119 TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
121 if (!uCount) return WBEM_S_FALSE;
122 if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER;
123 if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
126 if (ec->index + uCount > view->count) return WBEM_S_FALSE;
128 hr = create_class_object( view->table->name, iface, ec->index, apObjects );
129 if (hr != S_OK) return hr;
133 if (ec->index == view->count) return WBEM_S_FALSE;
134 if (uCount > 1) return WBEM_S_TIMEDOUT;
135 return WBEM_S_NO_ERROR;
138 static HRESULT WINAPI enum_class_object_NextAsync(
139 IEnumWbemClassObject *iface,
141 IWbemObjectSink *pSink )
143 FIXME("%p, %u, %p\n", iface, uCount, pSink);
147 static HRESULT WINAPI enum_class_object_Clone(
148 IEnumWbemClassObject *iface,
149 IEnumWbemClassObject **ppEnum )
151 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
153 TRACE("%p, %p\n", iface, ppEnum);
155 return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum );
158 static HRESULT WINAPI enum_class_object_Skip(
159 IEnumWbemClassObject *iface,
163 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
164 struct view *view = ec->query->view;
166 TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
168 if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
170 if (!view->count) return WBEM_S_FALSE;
172 if (nCount > view->count - ec->index)
174 ec->index = view->count - 1;
178 return WBEM_S_NO_ERROR;
181 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
183 enum_class_object_QueryInterface,
184 enum_class_object_AddRef,
185 enum_class_object_Release,
186 enum_class_object_Reset,
187 enum_class_object_Next,
188 enum_class_object_NextAsync,
189 enum_class_object_Clone,
190 enum_class_object_Skip
193 HRESULT EnumWbemClassObject_create(
194 IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj )
196 struct enum_class_object *ec;
198 TRACE("%p, %p\n", pUnkOuter, ppObj);
200 ec = heap_alloc( sizeof(*ec) );
201 if (!ec) return E_OUTOFMEMORY;
203 ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
206 addref_query( query );
209 *ppObj = &ec->IEnumWbemClassObject_iface;
211 TRACE("returning iface %p\n", *ppObj);
217 IWbemClassObject IWbemClassObject_iface;
220 IEnumWbemClassObject *iter;
224 static inline struct class_object *impl_from_IWbemClassObject(
225 IWbemClassObject *iface )
227 return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
230 static ULONG WINAPI class_object_AddRef(
231 IWbemClassObject *iface )
233 struct class_object *co = impl_from_IWbemClassObject( iface );
234 return InterlockedIncrement( &co->refs );
237 static ULONG WINAPI class_object_Release(
238 IWbemClassObject *iface )
240 struct class_object *co = impl_from_IWbemClassObject( iface );
241 LONG refs = InterlockedDecrement( &co->refs );
244 TRACE("destroying %p\n", co);
245 if (co->iter) IEnumWbemClassObject_Release( co->iter );
246 heap_free( co->name );
252 static HRESULT WINAPI class_object_QueryInterface(
253 IWbemClassObject *iface,
257 struct class_object *co = impl_from_IWbemClassObject( iface );
259 TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
261 if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
262 IsEqualGUID( riid, &IID_IUnknown ) )
268 FIXME("interface %s not implemented\n", debugstr_guid(riid));
269 return E_NOINTERFACE;
271 IWbemClassObject_AddRef( iface );
275 static HRESULT WINAPI class_object_GetQualifierSet(
276 IWbemClassObject *iface,
277 IWbemQualifierSet **ppQualSet )
279 FIXME("%p, %p\n", iface, ppQualSet);
283 static HRESULT WINAPI class_object_Get(
284 IWbemClassObject *iface,
291 struct class_object *co = impl_from_IWbemClassObject( iface );
292 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
293 struct view *view = ec->query->view;
295 TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
297 return get_propval( view, co->index, wszName, pVal, pType, plFlavor );
300 static HRESULT WINAPI class_object_Put(
301 IWbemClassObject *iface,
307 struct class_object *co = impl_from_IWbemClassObject( iface );
308 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
309 struct view *view = ec->query->view;
311 TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
313 return put_propval( view, co->index, wszName, pVal, Type );
316 static HRESULT WINAPI class_object_Delete(
317 IWbemClassObject *iface,
320 FIXME("%p, %s\n", iface, debugstr_w(wszName));
324 static HRESULT WINAPI class_object_GetNames(
325 IWbemClassObject *iface,
326 LPCWSTR wszQualifierName,
328 VARIANT *pQualifierVal,
331 struct class_object *co = impl_from_IWbemClassObject( iface );
332 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
334 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames);
336 if (wszQualifierName || pQualifierVal)
338 FIXME("qualifier not supported\n");
341 if (lFlags != WBEM_FLAG_ALWAYS)
343 FIXME("flags %08x not supported\n", lFlags);
346 return get_properties( ec->query->view, pNames );
349 static HRESULT WINAPI class_object_BeginEnumeration(
350 IWbemClassObject *iface,
353 FIXME("%p, %08x\n", iface, lEnumFlags);
357 static HRESULT WINAPI class_object_Next(
358 IWbemClassObject *iface,
365 FIXME("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
369 static HRESULT WINAPI class_object_EndEnumeration(
370 IWbemClassObject *iface )
372 FIXME("%p\n", iface);
376 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
377 IWbemClassObject *iface,
379 IWbemQualifierSet **ppQualSet )
381 FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
385 static HRESULT WINAPI class_object_Clone(
386 IWbemClassObject *iface,
387 IWbemClassObject **ppCopy )
389 FIXME("%p, %p\n", iface, ppCopy);
393 static HRESULT WINAPI class_object_GetObjectText(
394 IWbemClassObject *iface,
396 BSTR *pstrObjectText )
398 FIXME("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
402 static HRESULT WINAPI class_object_SpawnDerivedClass(
403 IWbemClassObject *iface,
405 IWbemClassObject **ppNewClass )
407 FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
411 static HRESULT WINAPI class_object_SpawnInstance(
412 IWbemClassObject *iface,
414 IWbemClassObject **ppNewInstance )
416 FIXME("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
420 static HRESULT WINAPI class_object_CompareTo(
421 IWbemClassObject *iface,
423 IWbemClassObject *pCompareTo )
425 FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
429 static HRESULT WINAPI class_object_GetPropertyOrigin(
430 IWbemClassObject *iface,
432 BSTR *pstrClassName )
434 FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
438 static HRESULT WINAPI class_object_InheritsFrom(
439 IWbemClassObject *iface,
440 LPCWSTR strAncestor )
442 FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
446 static UINT count_instances( IEnumWbemClassObject *iter )
449 while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
450 IEnumWbemClassObject_Reset( iter );
454 static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
462 *(UINT16 *)ptr = val;
468 *(UINT32 *)ptr = val;
471 FIXME("unhandled type %u\n", type);
476 static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
477 struct column **cols, BYTE **data )
479 static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
480 static const WCHAR typeW[] = {'T','y','p','e',0};
481 static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
482 struct column *columns;
484 IWbemClassObject *param;
486 HRESULT hr = E_OUTOFMEMORY;
491 count = count_instances( iter );
492 if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
493 if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
497 IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, ¶m, &count );
500 hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
501 if (hr != S_OK) goto error;
502 columns[i].name = heap_strdupW( V_BSTR( &val ) );
503 VariantClear( &val );
505 hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
506 if (hr != S_OK) goto error;
507 columns[i].type = V_UI4( &val );
508 columns[i].vartype = 0;
510 hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
511 if (hr != S_OK) goto error;
512 if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
513 offset += get_type_size( columns[i].type );
515 IWbemClassObject_Release( param );
524 for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
525 heap_free( columns );
530 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
534 struct column *columns;
538 hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
539 if (hr != S_OK) return hr;
541 if (!(table = create_table( name, num_cols, columns, 1, row, NULL )))
543 free_columns( columns, num_cols );
545 return E_OUTOFMEMORY;
547 if (!add_table( table )) free_table( table ); /* already exists */
551 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
553 static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
554 static const WCHAR outW[] = {'O','U','T',0};
555 static const WCHAR inW[] = {'I','N',0};
556 UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
559 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
560 sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
561 return struprW( ret );
564 static HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
565 IWbemClassObject **sig )
567 static const WCHAR selectW[] =
568 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
569 '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
570 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
571 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
572 'D','i','r','e','c','t','i','o','n','%','s',0};
573 static const WCHAR geW[] = {'>','=','0',0};
574 static const WCHAR leW[] = {'<','=','0',0};
575 UINT len = SIZEOF(selectW) + SIZEOF(geW);
576 IEnumWbemClassObject *iter;
580 len += strlenW( class ) + strlenW( method );
581 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
582 sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
584 hr = exec_query( query, &iter );
586 if (hr != S_OK) return hr;
588 if (!(name = build_signature_table_name( class, method, dir )))
590 IEnumWbemClassObject_Release( iter );
591 return E_OUTOFMEMORY;
593 hr = create_signature_table( iter, name );
594 IEnumWbemClassObject_Release( iter );
600 return get_object( name, sig );
603 static HRESULT WINAPI class_object_GetMethod(
604 IWbemClassObject *iface,
607 IWbemClassObject **ppInSignature,
608 IWbemClassObject **ppOutSignature )
610 struct class_object *co = impl_from_IWbemClassObject( iface );
613 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
615 hr = create_signature( co->name, wszName, PARAM_IN, ppInSignature );
616 if (hr != S_OK) return hr;
618 hr = create_signature( co->name, wszName, PARAM_OUT, ppOutSignature );
619 if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
623 static HRESULT WINAPI class_object_PutMethod(
624 IWbemClassObject *iface,
627 IWbemClassObject *pInSignature,
628 IWbemClassObject *pOutSignature )
630 FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
634 static HRESULT WINAPI class_object_DeleteMethod(
635 IWbemClassObject *iface,
638 FIXME("%p, %s\n", iface, debugstr_w(wszName));
642 static HRESULT WINAPI class_object_BeginMethodEnumeration(
643 IWbemClassObject *iface,
646 FIXME("%p, %08x\n", iface, lEnumFlags);
650 static HRESULT WINAPI class_object_NextMethod(
651 IWbemClassObject *iface,
654 IWbemClassObject **ppInSignature,
655 IWbemClassObject **ppOutSignature)
657 FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
661 static HRESULT WINAPI class_object_EndMethodEnumeration(
662 IWbemClassObject *iface )
664 FIXME("%p\n", iface);
668 static HRESULT WINAPI class_object_GetMethodQualifierSet(
669 IWbemClassObject *iface,
671 IWbemQualifierSet **ppQualSet)
673 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
677 static HRESULT WINAPI class_object_GetMethodOrigin(
678 IWbemClassObject *iface,
679 LPCWSTR wszMethodName,
682 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
686 static const IWbemClassObjectVtbl class_object_vtbl =
688 class_object_QueryInterface,
690 class_object_Release,
691 class_object_GetQualifierSet,
695 class_object_GetNames,
696 class_object_BeginEnumeration,
698 class_object_EndEnumeration,
699 class_object_GetPropertyQualifierSet,
701 class_object_GetObjectText,
702 class_object_SpawnDerivedClass,
703 class_object_SpawnInstance,
704 class_object_CompareTo,
705 class_object_GetPropertyOrigin,
706 class_object_InheritsFrom,
707 class_object_GetMethod,
708 class_object_PutMethod,
709 class_object_DeleteMethod,
710 class_object_BeginMethodEnumeration,
711 class_object_NextMethod,
712 class_object_EndMethodEnumeration,
713 class_object_GetMethodQualifierSet,
714 class_object_GetMethodOrigin
717 HRESULT create_class_object(
718 const WCHAR *name, IEnumWbemClassObject *iter, UINT index, IWbemClassObject **obj )
720 struct class_object *co;
722 TRACE("%s, %p\n", debugstr_w(name), obj);
724 co = heap_alloc( sizeof(*co) );
725 if (!co) return E_OUTOFMEMORY;
727 co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
729 co->name = heap_strdupW( name );
733 return E_OUTOFMEMORY;
737 if (iter) IEnumWbemClassObject_AddRef( iter );
739 *obj = &co->IWbemClassObject_iface;
741 TRACE("returning iface %p\n", *obj);