wbemprox: Implement IWbemQualifierSet::Get.

This commit is contained in:
Hans Leidekker 2013-01-25 17:34:00 +01:00 committed by Alexandre Julliard
parent d74cf43fbe
commit 236b4dae4a
5 changed files with 194 additions and 10 deletions

View File

@ -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}; {'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[] = static const WCHAR class_paramsW[] =
{'_','_','P','A','R','A','M','E','T','E','R','S',0}; {'_','_','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[] = static const WCHAR class_processorW[] =
{'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0};
static const WCHAR class_sounddeviceW[] = static const WCHAR class_sounddeviceW[] =
@ -110,12 +115,18 @@ static const WCHAR prop_drivetypeW[] =
{'D','r','i','v','e','T','y','p','e',0}; {'D','r','i','v','e','T','y','p','e',0};
static const WCHAR prop_filesystemW[] = static const WCHAR prop_filesystemW[] =
{'F','i','l','e','S','y','s','t','e','m',0}; {'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[] = static const WCHAR prop_freespaceW[] =
{'F','r','e','e','S','p','a','c','e',0}; {'F','r','e','e','S','p','a','c','e',0};
static const WCHAR prop_handleW[] = static const WCHAR prop_handleW[] =
{'H','a','n','d','l','e',0}; {'H','a','n','d','l','e',0};
static const WCHAR prop_idW[] =
{'I','D',0};
static const WCHAR prop_interfaceindexW[] = static const WCHAR prop_interfaceindexW[] =
{'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; {'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[] = static const WCHAR prop_lastbootuptimeW[] =
{'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0};
static const WCHAR prop_macaddressW[] = 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}; {'M','a','n','u','f','a','c','t','u','r','e','r',0};
static const WCHAR prop_maxclockspeedW[] = static const WCHAR prop_maxclockspeedW[] =
{'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; {'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[] = static const WCHAR prop_methodW[] =
{'M','e','t','h','o','d',0}; {'M','e','t','h','o','d',0};
static const WCHAR prop_modelW[] = static const WCHAR prop_modelW[] =
@ -164,6 +177,8 @@ static const WCHAR prop_speedW[] =
{'S','p','e','e','d',0}; {'S','p','e','e','d',0};
static const WCHAR prop_stateW[] = static const WCHAR prop_stateW[] =
{'S','t','a','t','e',0}; {'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[] = static const WCHAR prop_systemdirectoryW[] =
{'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0}; {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0};
static const WCHAR prop_systemnameW[] = static const WCHAR prop_systemnameW[] =
@ -249,7 +264,7 @@ static const struct column col_os[] =
{ prop_oslanguageW, CIM_UINT32, VT_I4 }, { prop_oslanguageW, CIM_UINT32, VT_I4 },
{ prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC } { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC }
}; };
static const struct column col_params[] = static const struct column col_param[] =
{ {
{ prop_classW, CIM_STRING }, { prop_classW, CIM_STRING },
{ prop_methodW, CIM_STRING }, { prop_methodW, CIM_STRING },
@ -282,6 +297,16 @@ static const struct column col_processor[] =
{ prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC },
{ prop_uniqueidW, CIM_STRING } { 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[] = static const struct column col_service[] =
{ {
{ prop_acceptpauseW, CIM_BOOLEAN }, { prop_acceptpauseW, CIM_BOOLEAN },
@ -436,7 +461,7 @@ struct record_operatingsystem
UINT32 oslanguage; UINT32 oslanguage;
const WCHAR *systemdirectory; const WCHAR *systemdirectory;
}; };
struct record_params struct record_param
{ {
const WCHAR *class; const WCHAR *class;
const WCHAR *method; const WCHAR *method;
@ -469,6 +494,16 @@ struct record_processor
const WCHAR *processor_id; const WCHAR *processor_id;
const WCHAR *unique_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 struct record_service
{ {
int accept_pause; int accept_pause;
@ -524,7 +559,7 @@ static const struct record_diskdrive data_diskdrive[] =
{ {
{ diskdrive_deviceidW, diskdrive_manufacturerW, diskdrive_modelW } { 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_returnvalueW, CIM_UINT32, VT_I4 },
{ class_processW, method_getownerW, -1, param_userW, CIM_STRING }, { 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_returnvalueW, CIM_UINT32, VT_I4 },
{ class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING } { 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[] = static const struct record_sounddevice data_sounddevice[] =
{ {
{ sounddevice_productnameW } { sounddevice_productnameW }
@ -1209,9 +1253,10 @@ static struct table builtin_classes[] =
{ class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, NULL, fill_logicaldisk }, { class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, NULL, fill_logicaldisk },
{ class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, NULL, fill_networkadapter }, { class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, NULL, fill_networkadapter },
{ class_osW, SIZEOF(col_os), col_os, 0, NULL, fill_os }, { 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_processW, SIZEOF(col_process), col_process, 0, NULL, fill_process },
{ class_processorW, SIZEOF(col_processor), col_processor, 0, NULL, fill_processor }, { 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_serviceW, SIZEOF(col_service), col_service, 0, NULL, fill_service },
{ class_sounddeviceW, SIZEOF(col_sounddevice), col_sounddevice, SIZEOF(data_sounddevice), (BYTE *)data_sounddevice }, { 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 }, { class_stdregprovW, SIZEOF(col_stdregprov), col_stdregprov, SIZEOF(data_stdregprov), (BYTE *)data_stdregprov },

View File

@ -546,8 +546,11 @@ static HRESULT WINAPI class_object_GetPropertyQualifierSet(
LPCWSTR wszProperty, LPCWSTR wszProperty,
IWbemQualifierSet **ppQualSet ) IWbemQualifierSet **ppQualSet )
{ {
FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); struct class_object *co = impl_from_IWbemClassObject( iface );
return WbemQualifierSet_create( NULL, (void **)ppQualSet );
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( static HRESULT WINAPI class_object_Clone(

View File

@ -35,6 +35,8 @@ struct qualifier_set
{ {
IWbemQualifierSet IWbemQualifierSet_iface; IWbemQualifierSet IWbemQualifierSet_iface;
LONG refs; LONG refs;
WCHAR *class;
WCHAR *member;
}; };
static inline struct qualifier_set *impl_from_IWbemQualifierSet( static inline struct qualifier_set *impl_from_IWbemQualifierSet(
@ -58,6 +60,8 @@ static ULONG WINAPI qualifier_set_Release(
if (!refs) if (!refs)
{ {
TRACE("destroying %p\n", set); TRACE("destroying %p\n", set);
heap_free( set->class );
heap_free( set->member );
heap_free( set ); heap_free( set );
} }
return refs; return refs;
@ -86,6 +90,83 @@ static HRESULT WINAPI qualifier_set_QueryInterface(
return S_OK; 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( static HRESULT WINAPI qualifier_set_Get(
IWbemQualifierSet *iface, IWbemQualifierSet *iface,
LPCWSTR wszName, LPCWSTR wszName,
@ -93,8 +174,10 @@ static HRESULT WINAPI qualifier_set_Get(
VARIANT *pVal, VARIANT *pVal,
LONG *plFlavor ) LONG *plFlavor )
{ {
struct qualifier_set *set = impl_from_IWbemQualifierSet( iface );
FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor); 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( static HRESULT WINAPI qualifier_set_Put(
@ -165,7 +248,7 @@ static const IWbemQualifierSetVtbl qualifier_set_vtbl =
}; };
HRESULT WbemQualifierSet_create( HRESULT WbemQualifierSet_create(
IUnknown *pUnkOuter, LPVOID *ppObj ) IUnknown *pUnkOuter, const WCHAR *class, const WCHAR *member, LPVOID *ppObj )
{ {
struct qualifier_set *set; struct qualifier_set *set;
@ -174,6 +257,18 @@ HRESULT WbemQualifierSet_create(
if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY;
set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl; 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; set->refs = 1;
*ppObj = &set->IWbemQualifierSet_iface; *ppObj = &set->IWbemQualifierSet_iface;

View File

@ -229,11 +229,17 @@ static void test_Win32_Process( IWbemServices *services )
static const WCHAR userW[] = {'U','s','e','r',0}; static const WCHAR userW[] = {'U','s','e','r',0};
static const WCHAR domainW[] = {'D','o','m','a','i','n',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 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','.', static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.',
'H','a','n','d','l','e','=','"','%','u','"',0}; '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; BSTR class, method;
IWbemClassObject *process, *out; IWbemClassObject *process, *out;
VARIANT user, domain, retval; IWbemQualifierSet *qualifiers;
VARIANT user, domain, retval, val;
LONG flavor;
CIMTYPE type; CIMTYPE type;
HRESULT hr; HRESULT hr;
@ -281,6 +287,41 @@ static void test_Win32_Process( IWbemServices *services )
ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
trace("%s\n", wine_dbgstr_w(V_BSTR(&domain))); 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( &user );
VariantClear( &domain ); VariantClear( &domain );
IWbemClassObject_Release( out ); IWbemClassObject_Release( out );

View File

@ -197,7 +197,7 @@ HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN
HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT, HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT,
struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; struct record *, IWbemClassObject **) DECLSPEC_HIDDEN;
HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) 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 process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN;
HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN;