wbemprox: Add support for evaluating ASSOCIATORS OF queries.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c69813bcd0
commit
8487265f81
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -29,25 +29,56 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
|
||||
|
||||
HRESULT create_view( const WCHAR *path, const struct keyword *keywordlist, const WCHAR *class,
|
||||
static HRESULT append_table( struct view *view, struct table *table )
|
||||
{
|
||||
struct table **tmp;
|
||||
if (!(tmp = heap_realloc( view->table, (view->table_count + 1) * sizeof(*tmp) ))) return E_OUTOFMEMORY;
|
||||
view->table = tmp;
|
||||
view->table[view->table_count++] = table;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT create_view( enum view_type type, const WCHAR *path, const struct keyword *keywordlist, const WCHAR *class,
|
||||
const struct property *proplist, const struct expr *cond, struct view **ret )
|
||||
{
|
||||
struct view *view = heap_alloc_zero( sizeof(*view) );
|
||||
|
||||
if (!view) return E_OUTOFMEMORY;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case VIEW_TYPE_ASSOCIATORS:
|
||||
view->path = path;
|
||||
view->keywordlist = keywordlist;
|
||||
break;
|
||||
|
||||
case VIEW_TYPE_SELECT:
|
||||
{
|
||||
struct table *table = grab_table( class );
|
||||
HRESULT hr;
|
||||
|
||||
if (table && (hr = append_table( view, table )) != S_OK) return hr;
|
||||
view->proplist = proplist;
|
||||
view->table = grab_table( class );
|
||||
view->cond = cond;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERR( "unhandled type %u\n", type );
|
||||
heap_free( view );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
view->type = type;
|
||||
*ret = view;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void destroy_view( struct view *view )
|
||||
{
|
||||
ULONG i;
|
||||
if (!view) return;
|
||||
if (view->table) release_table( view->table );
|
||||
for (i = 0; i < view->table_count; i++) release_table( view->table[i] );
|
||||
heap_free( view->table );
|
||||
heap_free( view->result );
|
||||
heap_free( view );
|
||||
}
|
||||
|
@ -440,24 +471,242 @@ HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond,
|
|||
return WBEM_E_INVALID_QUERY;
|
||||
}
|
||||
|
||||
HRESULT execute_view( struct view *view )
|
||||
static WCHAR *build_assoc_query( const WCHAR *class, UINT class_len )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','A','S','S','O','C','I','A','T','O','R','S',
|
||||
' ','W','H','E','R','E',' ','C','l','a','s','s','=','\'','%','s','\'',0};
|
||||
UINT len = class_len + ARRAY_SIZE(fmtW);
|
||||
WCHAR *ret;
|
||||
|
||||
if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
|
||||
swprintf( ret, len, fmtW, class );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT create_assoc_enum( const WCHAR *class, UINT class_len, IEnumWbemClassObject **iter )
|
||||
{
|
||||
WCHAR *query;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(query = build_assoc_query( class, class_len ))) return E_OUTOFMEMORY;
|
||||
hr = exec_query( query, iter );
|
||||
heap_free( query );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static WCHAR *build_antecedent_query( const WCHAR *assocclass, const WCHAR *dependent )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'S','E','L','E','C','T',' ','A','n','t','e','c','e','d','e','n','t',' ','F','R','O','M',' ','%','s',' ',
|
||||
'W','H','E','R','E',' ','D','e','p','e','n','d','e','n','t','=','\'','%','s','\'',0};
|
||||
UINT len = lstrlenW(assocclass) + lstrlenW(dependent) + ARRAY_SIZE(fmtW);
|
||||
WCHAR *ret;
|
||||
|
||||
if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
|
||||
swprintf( ret, len, fmtW, assocclass, dependent );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BSTR build_servername(void)
|
||||
{
|
||||
WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p;
|
||||
DWORD len = ARRAY_SIZE( server );
|
||||
|
||||
if (!(GetComputerNameW( server, &len ))) return NULL;
|
||||
for (p = server; *p; p++) *p = towupper( *p );
|
||||
return SysAllocString( server );
|
||||
}
|
||||
|
||||
static BSTR build_namespace(void)
|
||||
{
|
||||
static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
|
||||
return SysAllocString( cimv2W );
|
||||
}
|
||||
|
||||
static WCHAR *build_canonical_path( const WCHAR *relpath )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':',0};
|
||||
BSTR server, namespace;
|
||||
WCHAR *ret;
|
||||
UINT len, i;
|
||||
|
||||
if (!(server = build_servername())) return NULL;
|
||||
if (!(namespace = build_namespace()))
|
||||
{
|
||||
SysFreeString( server );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = ARRAY_SIZE( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + lstrlenW( relpath );
|
||||
if ((ret = heap_alloc( len * sizeof(WCHAR ) )))
|
||||
{
|
||||
len = swprintf( ret, len, fmtW, server, namespace );
|
||||
for (i = 0; i < lstrlenW( relpath ); i ++)
|
||||
{
|
||||
if (relpath[i] == '\'') ret[len++] = '"';
|
||||
else ret[len++] = relpath[i];
|
||||
}
|
||||
ret[len] = 0;
|
||||
}
|
||||
|
||||
SysFreeString( server );
|
||||
SysFreeString( namespace );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT get_antecedent( const WCHAR *assocclass, const WCHAR *dependent, BSTR *ret )
|
||||
{
|
||||
static const WCHAR antecedentW[] = {'A','n','t','e','c','e','d','e','n','t',0};
|
||||
WCHAR *fullpath, *str;
|
||||
IEnumWbemClassObject *iter = NULL;
|
||||
IWbemClassObject *obj;
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
ULONG count;
|
||||
VARIANT var;
|
||||
|
||||
if (!(fullpath = build_canonical_path( dependent ))) return E_OUTOFMEMORY;
|
||||
if (!(str = build_antecedent_query( assocclass, fullpath ))) goto done;
|
||||
if ((hr = exec_query( str, &iter )) != S_OK) goto done;
|
||||
|
||||
IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
|
||||
if (!count)
|
||||
{
|
||||
*ret = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = IWbemClassObject_Get( obj, antecedentW, 0, &var, NULL, NULL );
|
||||
IWbemClassObject_Release( obj );
|
||||
if (hr != S_OK) goto done;
|
||||
*ret = V_BSTR( &var );
|
||||
|
||||
done:
|
||||
if (iter) IEnumWbemClassObject_Release( iter );
|
||||
heap_free( str );
|
||||
heap_free( fullpath );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT do_query( const WCHAR *str, struct query **ret_query )
|
||||
{
|
||||
struct query *query;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(query = create_query())) return E_OUTOFMEMORY;
|
||||
if ((hr = parse_query( str, &query->view, &query->mem )) != S_OK || (hr = execute_view( query->view )) != S_OK)
|
||||
{
|
||||
release_query( query );
|
||||
return hr;
|
||||
}
|
||||
*ret_query = query;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT get_antecedent_table( const WCHAR *assocclass, const WCHAR *dependent, struct table **table )
|
||||
{
|
||||
BSTR antecedent = NULL;
|
||||
struct path *path = NULL;
|
||||
WCHAR *str = NULL;
|
||||
struct query *query = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
if ((hr = get_antecedent( assocclass, dependent, &antecedent )) != S_OK) return hr;
|
||||
if (!antecedent)
|
||||
{
|
||||
*table = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
if ((hr = parse_path( antecedent, &path )) != S_OK) goto done;
|
||||
if (!(str = query_from_path( path )))
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((hr = do_query( str, &query )) != S_OK) goto done;
|
||||
if (query->view->table_count) *table = addref_table( query->view->table[0] );
|
||||
else *table = NULL;
|
||||
|
||||
done:
|
||||
if (query) release_query( query );
|
||||
free_path( path );
|
||||
SysFreeString( antecedent );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT exec_assoc_view( struct view *view )
|
||||
{
|
||||
static const WCHAR assocclassW[] = {'A','s','s','o','c','C','l','a','s','s',0};
|
||||
IEnumWbemClassObject *iter = NULL;
|
||||
struct path *path;
|
||||
HRESULT hr;
|
||||
|
||||
if (view->keywordlist) FIXME( "ignoring keywords\n" );
|
||||
if ((hr = parse_path( view->path, &path )) != S_OK) return hr;
|
||||
|
||||
if ((hr = create_assoc_enum( path->class, path->class_len, &iter )) != S_OK) goto done;
|
||||
for (;;)
|
||||
{
|
||||
ULONG count;
|
||||
IWbemClassObject *obj;
|
||||
struct table *table;
|
||||
VARIANT var;
|
||||
|
||||
IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
|
||||
if (!count) break;
|
||||
|
||||
if ((hr = IWbemClassObject_Get( obj, assocclassW, 0, &var, NULL, NULL )) != S_OK)
|
||||
{
|
||||
IWbemClassObject_Release( obj );
|
||||
goto done;
|
||||
}
|
||||
IWbemClassObject_Release( obj );
|
||||
|
||||
hr = get_antecedent_table( V_BSTR(&var), view->path, &table );
|
||||
VariantClear( &var );
|
||||
if (hr != S_OK) goto done;
|
||||
|
||||
if (table && (hr = append_table( view, table )) != S_OK)
|
||||
{
|
||||
release_table( table );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (view->table_count)
|
||||
{
|
||||
if (!(view->result = heap_alloc_zero( view->table_count * sizeof(UINT) ))) hr = E_OUTOFMEMORY;
|
||||
else view->result_count = view->table_count;
|
||||
}
|
||||
|
||||
done:
|
||||
if (iter) IEnumWbemClassObject_Release( iter );
|
||||
free_path( path );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT exec_select_view( struct view *view )
|
||||
{
|
||||
UINT i, j = 0, len;
|
||||
enum fill_status status = FILL_STATUS_UNFILTERED;
|
||||
struct table *table;
|
||||
|
||||
if (!view->table) return S_OK;
|
||||
if (view->table->fill)
|
||||
if (!view->table_count) return S_OK;
|
||||
|
||||
table = view->table[0];
|
||||
if (table->fill)
|
||||
{
|
||||
clear_table( view->table );
|
||||
status = view->table->fill( view->table, view->cond );
|
||||
clear_table( table );
|
||||
status = table->fill( table, view->cond );
|
||||
}
|
||||
if (status == FILL_STATUS_FAILED) return WBEM_E_FAILED;
|
||||
if (!view->table->num_rows) return S_OK;
|
||||
if (!table->num_rows) return S_OK;
|
||||
|
||||
len = min( view->table->num_rows, 16 );
|
||||
len = min( table->num_rows, 16 );
|
||||
if (!(view->result = heap_alloc( len * sizeof(UINT) ))) return E_OUTOFMEMORY;
|
||||
|
||||
for (i = 0; i < view->table->num_rows; i++)
|
||||
for (i = 0; i < table->num_rows; i++)
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG val = 0;
|
||||
|
@ -471,13 +720,30 @@ HRESULT execute_view( struct view *view )
|
|||
view->result = tmp;
|
||||
}
|
||||
if (status == FILL_STATUS_FILTERED) val = 1;
|
||||
else if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr;
|
||||
else if ((hr = eval_cond( table, i, view->cond, &val, &type )) != S_OK) return hr;
|
||||
if (val) view->result[j++] = i;
|
||||
}
|
||||
view->count = j;
|
||||
|
||||
view->result_count = j;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT execute_view( struct view *view )
|
||||
{
|
||||
switch (view->type)
|
||||
{
|
||||
case VIEW_TYPE_ASSOCIATORS:
|
||||
return exec_assoc_view( view );
|
||||
|
||||
case VIEW_TYPE_SELECT:
|
||||
return exec_select_view( view );
|
||||
|
||||
default:
|
||||
ERR( "unhandled type %u\n", view->type );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
struct query *create_query(void)
|
||||
{
|
||||
struct query *query;
|
||||
|
@ -527,10 +793,9 @@ done:
|
|||
return hr;
|
||||
}
|
||||
|
||||
BOOL is_selected_prop( const struct view *view, const WCHAR *name )
|
||||
BOOL is_result_prop( const struct view *view, const WCHAR *name )
|
||||
{
|
||||
const struct property *prop = view->proplist;
|
||||
|
||||
if (!prop) return TRUE;
|
||||
while (prop)
|
||||
{
|
||||
|
@ -545,47 +810,21 @@ static BOOL is_system_prop( const WCHAR *name )
|
|||
return (name[0] == '_' && name[1] == '_');
|
||||
}
|
||||
|
||||
static BSTR build_servername( const struct view *view )
|
||||
{
|
||||
WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p;
|
||||
DWORD len = ARRAY_SIZE( server );
|
||||
|
||||
if (view->proplist) return NULL;
|
||||
|
||||
if (!(GetComputerNameW( server, &len ))) return NULL;
|
||||
for (p = server; *p; p++) *p = towupper( *p );
|
||||
return SysAllocString( server );
|
||||
}
|
||||
|
||||
static BSTR build_classname( const struct view *view )
|
||||
{
|
||||
return SysAllocString( view->table->name );
|
||||
}
|
||||
|
||||
static BSTR build_namespace( const struct view *view )
|
||||
{
|
||||
static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
|
||||
|
||||
if (view->proplist) return NULL;
|
||||
return SysAllocString( cimv2W );
|
||||
}
|
||||
|
||||
static BSTR build_proplist( const struct view *view, UINT index, UINT count, UINT *len )
|
||||
static BSTR build_proplist( const struct table *table, UINT row, UINT count, UINT *len )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','s','=','%','s',0};
|
||||
UINT i, j, offset, row = view->result[index];
|
||||
UINT i, j, offset;
|
||||
BSTR *values, ret = NULL;
|
||||
|
||||
if (!(values = heap_alloc( count * sizeof(BSTR) ))) return NULL;
|
||||
|
||||
*len = j = 0;
|
||||
for (i = 0; i < view->table->num_cols; i++)
|
||||
for (i = 0; i < table->num_cols; i++)
|
||||
{
|
||||
if (view->table->columns[i].type & COL_FLAG_KEY)
|
||||
if (table->columns[i].type & COL_FLAG_KEY)
|
||||
{
|
||||
const WCHAR *name = view->table->columns[i].name;
|
||||
|
||||
values[j] = get_value_bstr( view->table, row, i );
|
||||
const WCHAR *name = table->columns[i].name;
|
||||
values[j] = get_value_bstr( table, row, i );
|
||||
*len += lstrlenW( fmtW ) + lstrlenW( name ) + lstrlenW( values[j] );
|
||||
j++;
|
||||
}
|
||||
|
@ -593,12 +832,11 @@ static BSTR build_proplist( const struct view *view, UINT index, UINT count, UIN
|
|||
if ((ret = SysAllocStringLen( NULL, *len )))
|
||||
{
|
||||
offset = j = 0;
|
||||
for (i = 0; i < view->table->num_cols; i++)
|
||||
for (i = 0; i < table->num_cols; i++)
|
||||
{
|
||||
if (view->table->columns[i].type & COL_FLAG_KEY)
|
||||
if (table->columns[i].type & COL_FLAG_KEY)
|
||||
{
|
||||
const WCHAR *name = view->table->columns[i].name;
|
||||
|
||||
const WCHAR *name = table->columns[i].name;
|
||||
offset += swprintf( ret + offset, *len - offset, fmtW, name, values[j] );
|
||||
if (j < count - 1) ret[offset++] = ',';
|
||||
j++;
|
||||
|
@ -610,28 +848,30 @@ static BSTR build_proplist( const struct view *view, UINT index, UINT count, UIN
|
|||
return ret;
|
||||
}
|
||||
|
||||
static UINT count_key_columns( const struct view *view )
|
||||
static UINT count_key_columns( const struct table *table )
|
||||
{
|
||||
UINT i, num_keys = 0;
|
||||
|
||||
for (i = 0; i < view->table->num_cols; i++)
|
||||
for (i = 0; i < table->num_cols; i++)
|
||||
{
|
||||
if (view->table->columns[i].type & COL_FLAG_KEY) num_keys++;
|
||||
if (table->columns[i].type & COL_FLAG_KEY) num_keys++;
|
||||
}
|
||||
return num_keys;
|
||||
}
|
||||
|
||||
static BSTR build_relpath( const struct view *view, UINT index, const WCHAR *name )
|
||||
static BSTR build_relpath( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','s','.','%','s',0};
|
||||
BSTR class, proplist, ret = NULL;
|
||||
struct table *table = view->table[table_index];
|
||||
UINT row = view->result[result_index];
|
||||
UINT num_keys, len;
|
||||
|
||||
if (view->proplist) return NULL;
|
||||
|
||||
if (!(class = build_classname( view ))) return NULL;
|
||||
if (!(num_keys = count_key_columns( view ))) return class;
|
||||
if (!(proplist = build_proplist( view, index, num_keys, &len ))) goto done;
|
||||
if (!(class = SysAllocString( view->table[table_index]->name ))) return NULL;
|
||||
if (!(num_keys = count_key_columns( table ))) return class;
|
||||
if (!(proplist = build_proplist( table, row, num_keys, &len ))) goto done;
|
||||
|
||||
len += lstrlenW( fmtW ) + SysStringLen( class );
|
||||
if (!(ret = SysAllocStringLen( NULL, len ))) goto done;
|
||||
|
@ -643,7 +883,7 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BSTR build_path( const struct view *view, UINT index, const WCHAR *name )
|
||||
static BSTR build_path( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':','%','s',0};
|
||||
BSTR server, namespace = NULL, relpath = NULL, ret = NULL;
|
||||
|
@ -651,9 +891,9 @@ static BSTR build_path( const struct view *view, UINT index, const WCHAR *name )
|
|||
|
||||
if (view->proplist) return NULL;
|
||||
|
||||
if (!(server = build_servername( view ))) return NULL;
|
||||
if (!(namespace = build_namespace( view ))) goto done;
|
||||
if (!(relpath = build_relpath( view, index, name ))) goto done;
|
||||
if (!(server = build_servername())) return NULL;
|
||||
if (!(namespace = build_namespace())) goto done;
|
||||
if (!(relpath = build_relpath( view, table_index, result_index, name ))) goto done;
|
||||
|
||||
len = lstrlenW( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + SysStringLen( relpath );
|
||||
if (!(ret = SysAllocStringLen( NULL, len ))) goto done;
|
||||
|
@ -671,30 +911,30 @@ BOOL is_method( const struct table *table, UINT column )
|
|||
return table->columns[column].type & COL_FLAG_METHOD;
|
||||
}
|
||||
|
||||
static UINT count_properties( const struct view *view )
|
||||
static UINT count_properties( const struct table *table )
|
||||
{
|
||||
UINT i, num_props = 0;
|
||||
|
||||
for (i = 0; i < view->table->num_cols; i++)
|
||||
for (i = 0; i < table->num_cols; i++)
|
||||
{
|
||||
if (!is_method( view->table, i)) num_props++;
|
||||
if (!is_method( table, i )) num_props++;
|
||||
}
|
||||
return num_props;
|
||||
}
|
||||
|
||||
static UINT count_selected_properties( const struct view *view )
|
||||
static UINT count_result_properties( const struct view *view, UINT table_index )
|
||||
{
|
||||
const struct property *prop = view->proplist;
|
||||
UINT count;
|
||||
|
||||
if (!prop) return count_properties( view );
|
||||
if (!prop) return count_properties( view->table[table_index] );
|
||||
|
||||
count = 1;
|
||||
while ((prop = prop->next)) count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static HRESULT get_system_propval( const struct view *view, UINT index, const WCHAR *name,
|
||||
static HRESULT get_system_propval( const struct view *view, UINT table_index, UINT result_index, const WCHAR *name,
|
||||
VARIANT *ret, CIMTYPE *type, LONG *flavor )
|
||||
{
|
||||
static const WCHAR classW[] = {'_','_','C','L','A','S','S',0};
|
||||
|
@ -712,7 +952,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_BSTR;
|
||||
V_BSTR( ret ) = build_classname( view );
|
||||
V_BSTR( ret ) = SysAllocString( view->table[table_index]->name );
|
||||
}
|
||||
if (type) *type = CIM_STRING;
|
||||
return S_OK;
|
||||
|
@ -732,7 +972,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_BSTR;
|
||||
V_BSTR( ret ) = build_namespace( view );
|
||||
V_BSTR( ret ) = view->proplist ? NULL : build_namespace();
|
||||
}
|
||||
if (type) *type = CIM_STRING;
|
||||
return S_OK;
|
||||
|
@ -742,7 +982,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_BSTR;
|
||||
V_BSTR( ret ) = build_path( view, index, name );
|
||||
V_BSTR( ret ) = build_path( view, table_index, result_index, name );
|
||||
}
|
||||
if (type) *type = CIM_STRING;
|
||||
return S_OK;
|
||||
|
@ -752,7 +992,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_I4;
|
||||
V_I4( ret ) = count_selected_properties( view );
|
||||
V_I4( ret ) = count_result_properties( view, table_index );
|
||||
}
|
||||
if (type) *type = CIM_SINT32;
|
||||
return S_OK;
|
||||
|
@ -762,7 +1002,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_BSTR;
|
||||
V_BSTR( ret ) = build_relpath( view, index, name );
|
||||
V_BSTR( ret ) = build_relpath( view, table_index, result_index, name );
|
||||
}
|
||||
if (type) *type = CIM_STRING;
|
||||
return S_OK;
|
||||
|
@ -772,7 +1012,7 @@ static HRESULT get_system_propval( const struct view *view, UINT index, const WC
|
|||
if (ret)
|
||||
{
|
||||
V_VT( ret ) = VT_BSTR;
|
||||
V_BSTR( ret ) = build_servername( view );
|
||||
V_BSTR( ret ) = view->proplist ? NULL : build_servername();
|
||||
}
|
||||
if (type) *type = CIM_STRING;
|
||||
return S_OK;
|
||||
|
@ -871,6 +1111,9 @@ void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret )
|
|||
break;
|
||||
case VT_NULL:
|
||||
break;
|
||||
case VT_R4:
|
||||
V_R4( ret ) = *(FLOAT *)&val;
|
||||
break;
|
||||
default:
|
||||
ERR("unhandled variant type %u\n", type);
|
||||
return;
|
||||
|
@ -878,34 +1121,74 @@ void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret )
|
|||
V_VT( ret ) = type;
|
||||
}
|
||||
|
||||
HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret,
|
||||
CIMTYPE *type, LONG *flavor )
|
||||
static HRESULT map_view_index( const struct view *view, UINT index, UINT *table_index, UINT *result_index )
|
||||
{
|
||||
switch (view->type)
|
||||
{
|
||||
case VIEW_TYPE_SELECT:
|
||||
*table_index = 0;
|
||||
*result_index = index;
|
||||
break;
|
||||
|
||||
case VIEW_TYPE_ASSOCIATORS:
|
||||
*table_index = *result_index = index;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled view type %u\n", view->type );
|
||||
return WBEM_E_FAILED;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct table *get_view_table( const struct view *view, UINT index )
|
||||
{
|
||||
switch (view->type)
|
||||
{
|
||||
case VIEW_TYPE_SELECT:
|
||||
return view->table[0];
|
||||
|
||||
case VIEW_TYPE_ASSOCIATORS:
|
||||
return view->table[index];
|
||||
|
||||
default:
|
||||
ERR( "unhandled view type %u\n", view->type );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret, CIMTYPE *type,
|
||||
LONG *flavor )
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT column, row;
|
||||
UINT column, row, table_index, result_index;
|
||||
struct table *table;
|
||||
VARTYPE vartype;
|
||||
void *val_ptr = NULL;
|
||||
LONGLONG val;
|
||||
|
||||
if (is_system_prop( name )) return get_system_propval( view, index, name, ret, type, flavor );
|
||||
if (!view->count || !is_selected_prop( view, name )) return WBEM_E_NOT_FOUND;
|
||||
if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
|
||||
|
||||
hr = get_column_index( view->table, name, &column );
|
||||
if (hr != S_OK || is_method( view->table, column )) return WBEM_E_NOT_FOUND;
|
||||
if (is_system_prop( name )) return get_system_propval( view, table_index, result_index, name, ret, type, flavor );
|
||||
if (!view->result_count || !is_result_prop( view, name )) return WBEM_E_NOT_FOUND;
|
||||
|
||||
row = view->result[index];
|
||||
hr = get_value( view->table, row, column, &val );
|
||||
table = view->table[table_index];
|
||||
hr = get_column_index( table, name, &column );
|
||||
if (hr != S_OK || is_method( table, column )) return WBEM_E_NOT_FOUND;
|
||||
|
||||
row = view->result[result_index];
|
||||
hr = get_value( table, row, column, &val );
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
if (type) *type = view->table->columns[column].type & COL_TYPE_MASK;
|
||||
if (type) *type = table->columns[column].type & COL_TYPE_MASK;
|
||||
if (flavor) *flavor = 0;
|
||||
|
||||
if (!ret) return S_OK;
|
||||
|
||||
vartype = view->table->columns[column].vartype;
|
||||
if (view->table->columns[column].type & CIM_FLAG_ARRAY)
|
||||
vartype = table->columns[column].vartype;
|
||||
if (table->columns[column].type & CIM_FLAG_ARRAY)
|
||||
{
|
||||
CIMTYPE basetype = view->table->columns[column].type & CIM_TYPE_MASK;
|
||||
CIMTYPE basetype = table->columns[column].type & CIM_TYPE_MASK;
|
||||
|
||||
val_ptr = to_safearray( (const struct array *)(INT_PTR)val, basetype );
|
||||
if (!val_ptr) vartype = VT_NULL;
|
||||
|
@ -914,7 +1197,7 @@ HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VAR
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
switch (view->table->columns[column].type & COL_TYPE_MASK)
|
||||
switch (table->columns[column].type & COL_TYPE_MASK)
|
||||
{
|
||||
case CIM_BOOLEAN:
|
||||
if (!vartype) vartype = VT_BOOL;
|
||||
|
@ -950,14 +1233,17 @@ HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VAR
|
|||
break;
|
||||
case CIM_SINT64:
|
||||
vartype = VT_BSTR;
|
||||
val_ptr = get_value_bstr( view->table, row, column );
|
||||
val_ptr = get_value_bstr( table, row, column );
|
||||
break;
|
||||
case CIM_UINT64:
|
||||
vartype = VT_BSTR;
|
||||
val_ptr = get_value_bstr( view->table, row, column );
|
||||
val_ptr = get_value_bstr( table, row, column );
|
||||
break;
|
||||
case CIM_REAL32:
|
||||
if (!vartype) vartype = VT_R4;
|
||||
break;
|
||||
default:
|
||||
ERR("unhandled column type %u\n", view->table->columns[column].type);
|
||||
ERR("unhandled column type %u\n", table->columns[column].type);
|
||||
return WBEM_E_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1087,45 +1373,56 @@ HRESULT to_longlong( VARIANT *var, LONGLONG *val, CIMTYPE *type )
|
|||
HRESULT put_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *var, CIMTYPE type )
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT column, row = view->result[index];
|
||||
UINT row, column, table_index, result_index;
|
||||
struct table *table;
|
||||
LONGLONG val;
|
||||
|
||||
hr = get_column_index( view->table, name, &column );
|
||||
if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
|
||||
|
||||
table = view->table[table_index];
|
||||
hr = get_column_index( table, name, &column );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
FIXME("no support for creating new properties\n");
|
||||
return WBEM_E_FAILED;
|
||||
}
|
||||
if (is_method( view->table, column ) || !(view->table->columns[column].type & COL_FLAG_DYNAMIC))
|
||||
if (is_method( table, column ) || !(table->columns[column].type & COL_FLAG_DYNAMIC))
|
||||
return WBEM_E_FAILED;
|
||||
|
||||
hr = to_longlong( var, &val, &type );
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
return set_value( view->table, row, column, val, type );
|
||||
row = view->result[result_index];
|
||||
return set_value( table, row, column, val, type );
|
||||
}
|
||||
|
||||
HRESULT get_properties( const struct view *view, LONG flags, SAFEARRAY **props )
|
||||
HRESULT get_properties( const struct view *view, UINT index, LONG flags, SAFEARRAY **props )
|
||||
{
|
||||
SAFEARRAY *sa;
|
||||
BSTR str;
|
||||
UINT i, num_props = count_selected_properties( view );
|
||||
UINT i, table_index, result_index, num_props;
|
||||
struct table *table;
|
||||
HRESULT hr;
|
||||
LONG j;
|
||||
|
||||
if ((hr = map_view_index( view, index, &table_index, &result_index )) != S_OK) return hr;
|
||||
|
||||
num_props = count_result_properties( view, table_index );
|
||||
if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, num_props ))) return E_OUTOFMEMORY;
|
||||
|
||||
for (i = 0, j = 0; i < view->table->num_cols; i++)
|
||||
table = view->table[table_index];
|
||||
for (i = 0, j = 0; i < table->num_cols; i++)
|
||||
{
|
||||
BOOL is_system;
|
||||
|
||||
if (is_method( view->table, i )) continue;
|
||||
if (!is_selected_prop( view, view->table->columns[i].name )) continue;
|
||||
if (is_method( table, i )) continue;
|
||||
if (!is_result_prop( view, table->columns[i].name )) continue;
|
||||
|
||||
is_system = is_system_prop( view->table->columns[i].name );
|
||||
is_system = is_system_prop( table->columns[i].name );
|
||||
if ((flags & WBEM_FLAG_NONSYSTEM_ONLY) && is_system) continue;
|
||||
else if ((flags & WBEM_FLAG_SYSTEM_ONLY) && !is_system) continue;
|
||||
|
||||
str = SysAllocString( view->table->columns[i].name );
|
||||
str = SysAllocString( table->columns[i].name );
|
||||
if (!str || SafeArrayPutElement( sa, &j, str ) != S_OK)
|
||||
{
|
||||
SysFreeString( str );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue