Commit 8487265f authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

wbemprox: Add support for evaluating ASSOCIATORS OF queries.

parent c69813bc
......@@ -50,6 +50,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
static const WCHAR class_associatorsW[] =
{'_','_','A','S','S','O','C','I','A','T','O','R','S',0};
static const WCHAR class_baseboardW[] =
{'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0};
static const WCHAR class_biosW[] =
......@@ -137,6 +139,10 @@ static const WCHAR prop_antecedentW[] =
{'A','n','t','e','c','e','d','e','n','t',0};
static const WCHAR prop_architectureW[] =
{'A','r','c','h','i','t','e','c','t','u','r','e',0};
static const WCHAR prop_assocclassW[] =
{'A','s','s','o','c','C','l','a','s','s',0};
static const WCHAR prop_associatorW[] =
{'A','s','s','o','c','i','a','t','o','r',0};
static const WCHAR prop_attributesW[] =
{'A','t','t','r','i','b','u','t','e','s',0};
static const WCHAR prop_availabilityW[] =
......@@ -433,6 +439,12 @@ static const WCHAR prop_workingsetsizeW[] =
{'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0};
/* column definitions must be kept in sync with record structures below */
static const struct column col_associator[] =
{
{ prop_assocclassW, CIM_STRING },
{ prop_classW, CIM_STRING },
{ prop_associatorW, CIM_STRING }
};
static const struct column col_baseboard[] =
{
{ prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
......@@ -871,6 +883,12 @@ static const WCHAR videocontroller_statusW[] =
{'O','K',0};
#include "pshpack1.h"
struct record_associator
{
const WCHAR *assocclass;
const WCHAR *class;
const WCHAR *associator;
};
struct record_baseboard
{
const WCHAR *manufacturer;
......@@ -1214,6 +1232,11 @@ struct record_videocontroller
};
#include "poppack.h"
static const struct record_associator data_associator[] =
{
{ class_diskdrivetodiskpartitionW, class_diskpartitionW, class_diskdriveW },
{ class_logicaldisktopartitionW, class_logicaldiskW, class_diskpartitionW },
};
static const struct record_param data_param[] =
{
{ class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
......@@ -2489,9 +2512,9 @@ static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
if ((hr = parse_query( select2W, &query2->view, &query2->mem )) != S_OK) goto done;
if ((hr = execute_view( query2->view )) != S_OK) goto done;
if (!(ret = heap_alloc_zero( query->view->count * sizeof(*ret) ))) goto done;
if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
for (i = 0; i < query->view->count; i++)
for (i = 0; i < query->view->result_count; i++)
{
if ((hr = get_propval( query->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
......@@ -2502,10 +2525,10 @@ static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
VariantClear( &val );
}
*count = query->view->count;
*count = query->view->result_count;
done:
if (!ret) free_assocations( ret, query->view->count );
if (!ret) free_assocations( ret, query->view->result_count );
free_query( query );
free_query( query2 );
return ret;
......@@ -2754,10 +2777,10 @@ static struct association *get_logicaldisktopartition_pairs( UINT *count )
if ((hr = parse_query( select2W, &query2->view, &query2->mem )) != S_OK) goto done;
if ((hr = execute_view( query2->view )) != S_OK) goto done;
if (!(ret = heap_alloc_zero( query->view->count * sizeof(*ret) ))) goto done;
if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
/* assume fixed and removable disks are enumerated in the same order as partitions */
for (i = 0; i < query->view->count; i++)
for (i = 0; i < query->view->result_count; i++)
{
if ((hr = get_propval( query->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done;
if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
......@@ -2768,10 +2791,10 @@ static struct association *get_logicaldisktopartition_pairs( UINT *count )
VariantClear( &val );
}
*count = query->view->count;
*count = query->view->result_count;
done:
if (!ret) free_assocations( ret, query->view->count );
if (!ret) free_assocations( ret, query->view->result_count );
free_query( query );
free_query( query2 );
return ret;
......@@ -4266,6 +4289,7 @@ done:
#define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
static struct table builtin_classes[] =
{
{ class_associatorsW, C(col_associator), D(data_associator) },
{ class_baseboardW, C(col_baseboard), 0, 0, NULL, fill_baseboard },
{ class_biosW, C(col_bios), 0, 0, NULL, fill_bios },
{ class_cdromdriveW, C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
......
......@@ -113,6 +113,7 @@ static HRESULT WINAPI enum_class_object_Next(
{
struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
struct view *view = ec->query->view;
struct table *table;
static int once = 0;
HRESULT hr;
......@@ -123,14 +124,15 @@ static HRESULT WINAPI enum_class_object_Next(
if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
*puReturned = 0;
if (ec->index >= view->count) return WBEM_S_FALSE;
if (ec->index >= view->result_count) return WBEM_S_FALSE;
hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects );
table = get_view_table( view, ec->index );
hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
if (hr != S_OK) return hr;
ec->index++;
*puReturned = 1;
if (ec->index == view->count && uCount > 1) return WBEM_S_FALSE;
if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
if (uCount > 1) return WBEM_S_TIMEDOUT;
return WBEM_S_NO_ERROR;
}
......@@ -168,11 +170,11 @@ static HRESULT WINAPI enum_class_object_Skip(
if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
if (!view->count) return WBEM_S_FALSE;
if (!view->result_count) return WBEM_S_FALSE;
if (nCount > view->count - ec->index)
if (nCount > view->result_count - ec->index)
{
ec->index = view->count - 1;
ec->index = view->result_count - 1;
return WBEM_S_FALSE;
}
ec->index += nCount;
......@@ -491,7 +493,7 @@ static HRESULT WINAPI class_object_GetNames(
if (wszQualifierName || pQualifierVal)
FIXME("qualifier not supported\n");
return get_properties( ec->query->view, lFlags, pNames );
return get_properties( ec->query->view, co->index, lFlags, pNames );
}
static HRESULT WINAPI class_object_BeginEnumeration(
......@@ -519,17 +521,18 @@ static HRESULT WINAPI class_object_Next(
struct class_object *obj = impl_from_IWbemClassObject( iface );
struct enum_class_object *iter = impl_from_IEnumWbemClassObject( obj->iter );
struct view *view = iter->query->view;
struct table *table = get_view_table( view, obj->index );
BSTR prop;
HRESULT hr;
UINT i;
TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
for (i = obj->index_property; i < view->table->num_cols; i++)
for (i = obj->index_property; i < table->num_cols; i++)
{
if (is_method( view->table, i )) continue;
if (!is_selected_prop( view, view->table->columns[i].name )) continue;
if (!(prop = SysAllocString( view->table->columns[i].name ))) return E_OUTOFMEMORY;
if (is_method( table, i )) continue;
if (!is_result_prop( view, table->columns[i].name )) continue;
if (!(prop = SysAllocString( table->columns[i].name ))) return E_OUTOFMEMORY;
if ((hr = get_propval( view, obj->index, prop, pVal, pType, plFlavor )) != S_OK)
{
SysFreeString( prop );
......@@ -612,15 +615,16 @@ static BSTR get_object_text( const struct view *view, UINT index )
static const WCHAR fmtW[] =
{'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
UINT len, len_body, row = view->result[index];
struct table *table = get_view_table( view, index );
BSTR ret, body;
len = ARRAY_SIZE( fmtW );
len += lstrlenW( view->table->name );
if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
len += lstrlenW( table->name );
if (!(body = get_body_text( table, row, &len_body ))) return NULL;
len += len_body;
if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
swprintf( ret, len, fmtW, view->table->name, body );
swprintf( ret, len, fmtW, table->name, body );
SysFreeString( body );
return ret;
}
......@@ -660,12 +664,12 @@ static HRESULT WINAPI class_object_SpawnInstance(
{
struct class_object *co = impl_from_IWbemClassObject( iface );
struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
struct view *view = ec->query->view;
struct table *table = get_view_table( ec->query->view, co->index );
struct record *record;
TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
if (!(record = create_record( view->table ))) return E_OUTOFMEMORY;
if (!(record = create_record( table ))) return E_OUTOFMEMORY;
return create_class_object( co->name, NULL, 0, record, ppNewInstance );
}
......
......@@ -320,15 +320,7 @@ static HRESULT WINAPI wbem_services_QueryObjectSink(
return WBEM_E_FAILED;
}
struct path
{
WCHAR *class;
UINT class_len;
WCHAR *filter;
UINT filter_len;
};
static HRESULT parse_path( const WCHAR *str, struct path **ret )
HRESULT parse_path( const WCHAR *str, struct path **ret )
{
struct path *path;
const WCHAR *p = str, *q;
......@@ -397,14 +389,15 @@ static HRESULT parse_path( const WCHAR *str, struct path **ret )
return S_OK;
}
static void free_path( struct path *path )
void free_path( struct path *path )
{
if (!path) return;
heap_free( path->class );
heap_free( path->filter );
heap_free( path );
}
static WCHAR *query_from_path( const struct path *path )
WCHAR *query_from_path( const struct path *path )
{
static const WCHAR selectW[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ',
......@@ -819,6 +812,7 @@ static HRESULT WINAPI wbem_services_ExecMethod(
struct path *path;
WCHAR *str;
class_method *func;
struct table *table;
HRESULT hr;
TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath),
......@@ -846,10 +840,11 @@ static HRESULT WINAPI wbem_services_ExecMethod(
hr = EnumWbemClassObject_create( query, (void **)&result );
if (hr != S_OK) goto done;
hr = create_class_object( query->view->table->name, result, 0, NULL, &obj );
table = get_view_table( query->view, 0 );
hr = create_class_object( table->name, result, 0, NULL, &obj );
if (hr != S_OK) goto done;
hr = get_method( query->view->table, strMethodName, &func );
hr = get_method( table, strMethodName, &func );
if (hr != S_OK) goto done;
hr = func( obj, pInParams, ppOutParams );
......
......@@ -155,15 +155,23 @@ struct keyword
const struct keyword *next;
};
enum view_type
{
VIEW_TYPE_SELECT,
VIEW_TYPE_ASSOCIATORS,
};
struct view
{
enum view_type type;
const WCHAR *path; /* ASSOCIATORS OF query */
const struct keyword *keywordlist;
const struct property *proplist;
struct table *table;
const struct property *proplist; /* SELECT query */
const struct expr *cond;
UINT table_count;
struct table **table;
UINT result_count;
UINT *result;
UINT count;
};
struct query
......@@ -173,16 +181,29 @@ struct query
struct list mem;
};
struct path
{
WCHAR *class;
UINT class_len;
WCHAR *filter;
UINT filter_len;
};
HRESULT parse_path( const WCHAR *, struct path ** ) DECLSPEC_HIDDEN;
void free_path( struct path * ) DECLSPEC_HIDDEN;
WCHAR *query_from_path( const struct path * ) DECLSPEC_HIDDEN;
struct query *create_query(void) DECLSPEC_HIDDEN;
void free_query( struct query * ) DECLSPEC_HIDDEN;
struct query *addref_query( struct query * ) DECLSPEC_HIDDEN;
void release_query( struct query *query ) DECLSPEC_HIDDEN;
HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN;
HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN;
HRESULT create_view( const WCHAR *, const struct keyword *, const WCHAR *, const struct property *,
HRESULT create_view( enum view_type, const WCHAR *, const struct keyword *, const WCHAR *, const struct property *,
const struct expr *, struct view ** ) DECLSPEC_HIDDEN;
void destroy_view( struct view * ) DECLSPEC_HIDDEN;
HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN;
struct table *get_view_table( const struct view *, UINT ) DECLSPEC_HIDDEN;
void init_table_list( void ) DECLSPEC_HIDDEN;
struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN;
struct table *addref_table( struct table * ) DECLSPEC_HIDDEN;
......@@ -202,15 +223,14 @@ BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN;
HRESULT set_value( const struct table *, UINT, UINT, LONGLONG, CIMTYPE ) DECLSPEC_HIDDEN;
BOOL is_method( const struct table *, UINT ) DECLSPEC_HIDDEN;
HRESULT get_method( const struct table *, const WCHAR *, class_method ** ) DECLSPEC_HIDDEN;
HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *,
CIMTYPE *, LONG * ) DECLSPEC_HIDDEN;
HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE *, LONG * ) DECLSPEC_HIDDEN;
HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE ) DECLSPEC_HIDDEN;
HRESULT to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN;
SAFEARRAY *to_safearray( const struct array *, CIMTYPE ) DECLSPEC_HIDDEN;
VARTYPE to_vartype( CIMTYPE ) DECLSPEC_HIDDEN;
void destroy_array( struct array *, CIMTYPE ) DECLSPEC_HIDDEN;
BOOL is_selected_prop( const struct view *, const WCHAR * ) DECLSPEC_HIDDEN;
HRESULT get_properties( const struct view *, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN;
BOOL is_result_prop( const struct view *, const WCHAR * ) DECLSPEC_HIDDEN;
HRESULT get_properties( const struct view *, UINT, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN;
HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN;
BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN;
......
......@@ -289,7 +289,7 @@ associatorsof:
struct parser *parser = ctx;
struct view *view;
hr = create_view( $3, NULL, NULL, NULL, NULL, &view );
hr = create_view( VIEW_TYPE_ASSOCIATORS, $3, NULL, NULL, NULL, NULL, &view );
if (hr != S_OK)
YYABORT;
......@@ -301,7 +301,7 @@ associatorsof:
struct parser *parser = ctx;
struct view *view;
hr = create_view( $3, $5, NULL, NULL, NULL, &view );
hr = create_view( VIEW_TYPE_ASSOCIATORS, $3, $5, NULL, NULL, NULL, &view );
if (hr != S_OK)
YYABORT;
......@@ -316,7 +316,7 @@ select:
struct parser *parser = ctx;
struct view *view;
hr = create_view( NULL, NULL, $3, NULL, NULL, &view );
hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $3, NULL, NULL, &view );
if (hr != S_OK)
YYABORT;
......@@ -328,7 +328,7 @@ select:
struct parser *parser = ctx;
struct view *view;
hr = create_view( NULL, NULL, $4, $2, NULL, &view );
hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $4, $2, NULL, &view );
if (hr != S_OK)
YYABORT;
......@@ -340,7 +340,7 @@ select:
struct parser *parser = ctx;
struct view *view;
hr = create_view( NULL, NULL, $4, $2, $6, &view );
hr = create_view( VIEW_TYPE_SELECT, NULL, NULL, $4, $2, $6, &view );
if (hr != S_OK)
YYABORT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment