From 236b4dae4ace5fe5c994646dafa8d15ff5c940e7 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 25 Jan 2013 17:34:00 +0100 Subject: [PATCH] wbemprox: Implement IWbemQualifierSet::Get. --- dlls/wbemprox/builtin.c | 53 +++++++++++++++-- dlls/wbemprox/class.c | 7 ++- dlls/wbemprox/qualifier.c | 99 +++++++++++++++++++++++++++++++- dlls/wbemprox/tests/query.c | 43 +++++++++++++- dlls/wbemprox/wbemprox_private.h | 2 +- 5 files changed, 194 insertions(+), 10 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 2e2e24b4422..5f6e62f3760 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -61,6 +61,11 @@ static const WCHAR class_osW[] = {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; static const WCHAR class_paramsW[] = {'_','_','P','A','R','A','M','E','T','E','R','S',0}; +static const WCHAR class_qualifiersW[] = + {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; +static const WCHAR class_process_getowner_outW[] = + {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W', + 'N','E','R','_','O','U','T',0}; static const WCHAR class_processorW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; static const WCHAR class_sounddeviceW[] = @@ -110,12 +115,18 @@ static const WCHAR prop_drivetypeW[] = {'D','r','i','v','e','T','y','p','e',0}; static const WCHAR prop_filesystemW[] = {'F','i','l','e','S','y','s','t','e','m',0}; +static const WCHAR prop_flavorW[] = + {'F','l','a','v','o','r',0}; static const WCHAR prop_freespaceW[] = {'F','r','e','e','S','p','a','c','e',0}; static const WCHAR prop_handleW[] = {'H','a','n','d','l','e',0}; +static const WCHAR prop_idW[] = + {'I','D',0}; static const WCHAR prop_interfaceindexW[] = {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; +static const WCHAR prop_intvalueW[] = + {'I','n','t','e','g','e','r','V','a','l','u','e',0}; static const WCHAR prop_lastbootuptimeW[] = {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; static const WCHAR prop_macaddressW[] = @@ -124,6 +135,8 @@ static const WCHAR prop_manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; static const WCHAR prop_maxclockspeedW[] = {'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; +static const WCHAR prop_memberW[] = + {'M','e','m','b','e','r',0}; static const WCHAR prop_methodW[] = {'M','e','t','h','o','d',0}; static const WCHAR prop_modelW[] = @@ -164,6 +177,8 @@ static const WCHAR prop_speedW[] = {'S','p','e','e','d',0}; static const WCHAR prop_stateW[] = {'S','t','a','t','e',0}; +static const WCHAR prop_strvalueW[] = + {'S','t','r','i','n','g','V','a','l','u','e',0}; static const WCHAR prop_systemdirectoryW[] = {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0}; static const WCHAR prop_systemnameW[] = @@ -249,7 +264,7 @@ static const struct column col_os[] = { prop_oslanguageW, CIM_UINT32, VT_I4 }, { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC } }; -static const struct column col_params[] = +static const struct column col_param[] = { { prop_classW, CIM_STRING }, { prop_methodW, CIM_STRING }, @@ -282,6 +297,16 @@ static const struct column col_processor[] = { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_uniqueidW, CIM_STRING } }; +static const struct column col_qualifier[] = +{ + { prop_classW, CIM_STRING }, + { prop_memberW, CIM_STRING }, + { prop_typeW, CIM_UINT32 }, + { prop_flavorW, CIM_SINT32 }, + { prop_nameW, CIM_STRING }, + { prop_intvalueW, CIM_SINT32 }, + { prop_strvalueW, CIM_STRING } +}; static const struct column col_service[] = { { prop_acceptpauseW, CIM_BOOLEAN }, @@ -436,7 +461,7 @@ struct record_operatingsystem UINT32 oslanguage; const WCHAR *systemdirectory; }; -struct record_params +struct record_param { const WCHAR *class; const WCHAR *method; @@ -469,6 +494,16 @@ struct record_processor const WCHAR *processor_id; const WCHAR *unique_id; }; +struct record_qualifier +{ + const WCHAR *class; + const WCHAR *member; + UINT32 type; + INT32 flavor; + const WCHAR *name; + INT32 intvalue; + const WCHAR *strvalue; +}; struct record_service { int accept_pause; @@ -524,7 +559,7 @@ static const struct record_diskdrive data_diskdrive[] = { { diskdrive_deviceidW, diskdrive_manufacturerW, diskdrive_modelW } }; -static const struct record_params data_params[] = +static const struct record_param data_param[] = { { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, { class_processW, method_getownerW, -1, param_userW, CIM_STRING }, @@ -548,6 +583,15 @@ static const struct record_params data_params[] = { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING } }; + +#define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\ + WBEM_FLAVOR_ORIGIN_PROPAGATED) + +static const struct record_qualifier data_qualifier[] = +{ + { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 }, + { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 } +}; static const struct record_sounddevice data_sounddevice[] = { { sounddevice_productnameW } @@ -1209,9 +1253,10 @@ static struct table builtin_classes[] = { class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, NULL, fill_logicaldisk }, { class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, NULL, fill_networkadapter }, { class_osW, SIZEOF(col_os), col_os, 0, NULL, fill_os }, - { class_paramsW, SIZEOF(col_params), col_params, SIZEOF(data_params), (BYTE *)data_params }, + { class_paramsW, SIZEOF(col_param), col_param, SIZEOF(data_param), (BYTE *)data_param }, { class_processW, SIZEOF(col_process), col_process, 0, NULL, fill_process }, { class_processorW, SIZEOF(col_processor), col_processor, 0, NULL, fill_processor }, + { class_qualifiersW, SIZEOF(col_qualifier), col_qualifier, SIZEOF(data_qualifier), (BYTE *)data_qualifier }, { class_serviceW, SIZEOF(col_service), col_service, 0, NULL, fill_service }, { class_sounddeviceW, SIZEOF(col_sounddevice), col_sounddevice, SIZEOF(data_sounddevice), (BYTE *)data_sounddevice }, { class_stdregprovW, SIZEOF(col_stdregprov), col_stdregprov, SIZEOF(data_stdregprov), (BYTE *)data_stdregprov }, diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c index 616c5213ca3..f47987d9cf6 100644 --- a/dlls/wbemprox/class.c +++ b/dlls/wbemprox/class.c @@ -546,8 +546,11 @@ static HRESULT WINAPI class_object_GetPropertyQualifierSet( LPCWSTR wszProperty, IWbemQualifierSet **ppQualSet ) { - FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); - return WbemQualifierSet_create( NULL, (void **)ppQualSet ); + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); + + return WbemQualifierSet_create( NULL, co->name, wszProperty, (void **)ppQualSet ); } static HRESULT WINAPI class_object_Clone( diff --git a/dlls/wbemprox/qualifier.c b/dlls/wbemprox/qualifier.c index b73bf1df6f1..b410534c306 100644 --- a/dlls/wbemprox/qualifier.c +++ b/dlls/wbemprox/qualifier.c @@ -35,6 +35,8 @@ struct qualifier_set { IWbemQualifierSet IWbemQualifierSet_iface; LONG refs; + WCHAR *class; + WCHAR *member; }; static inline struct qualifier_set *impl_from_IWbemQualifierSet( @@ -58,6 +60,8 @@ static ULONG WINAPI qualifier_set_Release( if (!refs) { TRACE("destroying %p\n", set); + heap_free( set->class ); + heap_free( set->member ); heap_free( set ); } return refs; @@ -86,6 +90,83 @@ static HRESULT WINAPI qualifier_set_QueryInterface( return S_OK; } +static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, const WCHAR *name, + IEnumWbemClassObject **iter ) +{ + static const WCHAR fmtW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',' ', + 'A','N','D',' ','N','a','m','e','=','\'','%','s','\'',0}; + static const WCHAR fmt2W[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',0}; + static const WCHAR noneW[] = {'_','_','N','O','N','E',0}; + WCHAR *query; + HRESULT hr; + int len; + + if (!member) member = noneW; + len = strlenW( class ) + strlenW( member ); + if (name) len += strlenW( name ) + SIZEOF(fmtW); + else len += SIZEOF(fmt2W); + + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + if (name) sprintfW( query, fmtW, class, member, name ); + else sprintfW( query, fmt2W, class, member ); + + hr = exec_query( query, iter ); + heap_free( query ); + return hr; +} + +static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, const WCHAR *name, + VARIANT *val, LONG *flavor ) +{ + static const WCHAR qualifiersW[] = {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; + static const WCHAR intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0}; + static const WCHAR strvalueW[] = {'S','t','r','i','n','g','V','a','l','u','e',0}; + static const WCHAR flavorW[] = {'F','l','a','v','o','r',0}; + static const WCHAR typeW[] = {'T','y','p','e',0}; + IEnumWbemClassObject *iter; + IWbemClassObject *obj; + VARIANT var; + HRESULT hr; + + hr = create_qualifier_enum( class, member, name, &iter ); + if (FAILED( hr )) return hr; + + hr = create_class_object( qualifiersW, iter, 0, NULL, &obj ); + IEnumWbemClassObject_Release( iter ); + if (FAILED( hr )) return hr; + + if (flavor) + { + hr = IWbemClassObject_Get( obj, flavorW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + *flavor = V_I4( &var ); + } + hr = IWbemClassObject_Get( obj, typeW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + switch (V_UI4( &var )) + { + case CIM_STRING: + hr = IWbemClassObject_Get( obj, strvalueW, 0, val, NULL, NULL ); + break; + case CIM_SINT32: + hr = IWbemClassObject_Get( obj, intvalueW, 0, val, NULL, NULL ); + break; + default: + ERR("unhandled type %u\n", V_UI4( &var )); + break; + } + +done: + IWbemClassObject_Release( obj ); + return hr; +} + static HRESULT WINAPI qualifier_set_Get( IWbemQualifierSet *iface, LPCWSTR wszName, @@ -93,8 +174,10 @@ static HRESULT WINAPI qualifier_set_Get( VARIANT *pVal, LONG *plFlavor ) { + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor); - return E_NOTIMPL; + return get_qualifier_value( set->class, set->member, wszName, pVal, plFlavor ); } static HRESULT WINAPI qualifier_set_Put( @@ -165,7 +248,7 @@ static const IWbemQualifierSetVtbl qualifier_set_vtbl = }; HRESULT WbemQualifierSet_create( - IUnknown *pUnkOuter, LPVOID *ppObj ) + IUnknown *pUnkOuter, const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) { struct qualifier_set *set; @@ -174,6 +257,18 @@ HRESULT WbemQualifierSet_create( if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl; + if (!(set->class = heap_strdupW( class ))) + { + heap_free( set ); + return E_OUTOFMEMORY; + } + if (!member) set->member = NULL; + else if (!(set->member = heap_strdupW( member ))) + { + heap_free( set->class ); + heap_free( set ); + return E_OUTOFMEMORY; + } set->refs = 1; *ppObj = &set->IWbemQualifierSet_iface; diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index 04c87b7a5b9..014bac49814 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -229,11 +229,17 @@ static void test_Win32_Process( IWbemServices *services ) static const WCHAR userW[] = {'U','s','e','r',0}; static const WCHAR domainW[] = {'D','o','m','a','i','n',0}; static const WCHAR processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0}; + static const WCHAR idW[] = {'I','D',0}; static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.', 'H','a','n','d','l','e','=','"','%','u','"',0}; + static const LONG expected_flavor = WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | + WBEM_FLAVOR_NOT_OVERRIDABLE | + WBEM_FLAVOR_ORIGIN_PROPAGATED; BSTR class, method; IWbemClassObject *process, *out; - VARIANT user, domain, retval; + IWbemQualifierSet *qualifiers; + VARIANT user, domain, retval, val; + LONG flavor; CIMTYPE type; HRESULT hr; @@ -281,6 +287,41 @@ static void test_Win32_Process( IWbemServices *services ) ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); trace("%s\n", wine_dbgstr_w(V_BSTR(&domain))); + hr = IWbemClassObject_GetPropertyQualifierSet( out, userW, &qualifiers ); + ok( hr == S_OK, "failed to get qualifier set %08x\n", hr ); + + flavor = -1; + V_I4(&val) = -1; + V_VT(&val) = VT_ERROR; + hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flavor == expected_flavor, "got %d\n", flavor ); + ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) ); + ok( V_I4(&val) == 0, "got %u\n", V_I4(&val) ); + VariantClear( &val ); + + IWbemQualifierSet_Release( qualifiers ); + hr = IWbemClassObject_GetPropertyQualifierSet( out, domainW, &qualifiers ); + ok( hr == S_OK, "failed to get qualifier set %08x\n", hr ); + + flavor = -1; + V_I4(&val) = -1; + V_VT(&val) = VT_ERROR; + hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flavor == expected_flavor, "got %d\n", flavor ); + ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) ); + ok( V_I4(&val) == 1, "got %u\n", V_I4(&val) ); + VariantClear( &val ); + + IWbemQualifierSet_Release( qualifiers ); + hr = IWbemClassObject_GetPropertyQualifierSet( out, returnvalueW, &qualifiers ); + ok( hr == S_OK, "failed to get qualifier set %08x\n", hr ); + + hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor ); + ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr ); + + IWbemQualifierSet_Release( qualifiers ); VariantClear( &user ); VariantClear( &domain ); IWbemClassObject_Release( out ); diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 621603df26f..f1d411961c6 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -197,7 +197,7 @@ HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT, struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPEC_HIDDEN; -HRESULT WbemQualifierSet_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemQualifierSet_create(IUnknown *, const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN;