From 39bac1e32b3a802ce3f40067fdf63581821092f8 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 10 Sep 2019 17:09:11 +0200 Subject: [PATCH] wbemprox: Implement Win32_LogicalDiskToPartition. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/wbemprox/builtin.c | 123 ++++++++++++++++++++++++++++++++++++ dlls/wbemprox/tests/query.c | 5 +- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 299a2edc71d..93d842708fa 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -76,6 +76,8 @@ static const WCHAR class_logicaldiskW[] = {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; static const WCHAR class_logicaldisk2W[] = {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR class_logicaldisktopartitionW[] = + {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0}; static const WCHAR class_networkadapterW[] = {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; static const WCHAR class_networkadapterconfigW[] = @@ -129,6 +131,8 @@ static const WCHAR prop_adaptertypeidW[] = {'A','d','a','p','t','e','r','T','y','p','e','I','D',0}; static const WCHAR prop_addresswidthW[] = {'A','d','d','r','e','s','s','W','i','d','t','h',0}; +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_attributesW[] = @@ -183,6 +187,8 @@ static const WCHAR prop_defaultipgatewayW[] = {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0}; static const WCHAR prop_defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0}; +static const WCHAR prop_dependentW[] = + {'D','e','p','e','n','d','e','n','t',0}; static const WCHAR prop_descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; static const WCHAR prop_destinationW[] = @@ -533,6 +539,11 @@ static const struct column col_logicaldisk[] = { prop_volumenameW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC } }; +static const struct column col_logicaldisktopartition[] = +{ + { prop_antecedentW, CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_dependentW, CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY } +}; static const struct column col_networkadapter[] = { { prop_adaptertypeW, CIM_STRING }, @@ -961,6 +972,11 @@ struct record_logicaldisk const WCHAR *volumename; const WCHAR *volumeserialnumber; }; +struct record_logicaldisktopartition +{ + const WCHAR *antecedent; + const WCHAR *dependent; +}; struct record_networkadapter { const WCHAR *adaptertype; @@ -2599,6 +2615,112 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr return status; } +struct association +{ + WCHAR *ref; + WCHAR *ref2; +}; + +static void free_assocations( struct association *assoc, UINT count ) +{ + UINT i; + if (!assoc) return; + for (i = 0; i < count; i++) + { + heap_free( assoc[i].ref ); + heap_free( assoc[i].ref2 ); + } + heap_free( assoc ); +} + +static struct association *get_logicaldisktopartition_pairs( UINT *count ) +{ + static const WCHAR pathW[] = + {'_','_','P','A','T','H',0}; + static const WCHAR selectW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', + 'D','i','s','k','P','a','r','t','i','t','i','o','n',0}; + static const WCHAR select2W[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k',' ','W','H','E','R','E',' ', + 'D','r','i','v','e','T','y','p','e','=','2',' ','O','R',' ','D','r','i','v','e','T','y','p','e','=','3',0}; + struct association *ret = NULL; + struct query *query, *query2 = NULL; + VARIANT val; + HRESULT hr; + UINT i; + + if (!(query = create_query())) return NULL; + if ((hr = parse_query( selectW, &query->view, &query->mem )) != S_OK) goto done; + if ((hr = execute_view( query->view )) != S_OK) goto done; + + if (!(query2 = create_query())) return FALSE; + 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; + + /* assume fixed and removable disks are enumerated in the same order as partitions */ + for (i = 0; i < query->view->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; + VariantClear( &val ); + + if ((hr = get_propval( query2->view, i, pathW, &val, NULL, NULL )) != S_OK) goto done; + if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done; + VariantClear( &val ); + } + + *count = query->view->count; + +done: + if (!ret) free_assocations( ret, query->view->count ); + free_query( query ); + free_query( query2 ); + return ret; +} + +static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond ) +{ + struct record_logicaldisktopartition *rec; + UINT i, row = 0, offset = 0, count = 0; + enum fill_status status = FILL_STATUS_UNFILTERED; + struct association *assoc; + + if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED; + if (!count) + { + free_assocations( assoc, count ); + return FILL_STATUS_UNFILTERED; + } + if (!resize_table( table, count, sizeof(*rec) )) + { + free_assocations( assoc, count ); + return FILL_STATUS_FAILED; + } + + for (i = 0; i < count; i++) + { + rec = (struct record_logicaldisktopartition *)(table->data + offset); + rec->antecedent = assoc[i].ref; + rec->dependent = assoc[i].ref2; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + + heap_free( assoc ); + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + static UINT16 get_connection_status( IF_OPER_STATUS status ) { switch (status) @@ -4061,6 +4183,7 @@ static struct table builtin_classes[] = { class_ip4routetableW, C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable }, { class_logicaldiskW, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk }, { class_logicaldisk2W, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk }, + { class_logicaldisktopartitionW, C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition }, { class_networkadapterW, C(col_networkadapter), 0, 0, NULL, fill_networkadapter }, { class_networkadapterconfigW, C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig }, { class_osW, C(col_os), 0, 0, NULL, fill_os }, diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index b180cfc92f8..6edb0d0f09c 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -123,8 +123,11 @@ static void test_select( IWbemServices *services ) static const WCHAR query13[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S', ' ','W','H','E','R','E',' ','N','U','L','L',' ','=',' ','N','A','M','E', 0}; + static const WCHAR query14[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0}; static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7, query8, query9, query10, - query11, query12, query13 }; + query11, query12, query13, query14 }; HRESULT hr; IEnumWbemClassObject *result; BSTR wql = SysAllocString( wqlW );