From: Hans Leidekker hans@codeweavers.com
--- dlls/wbemprox/builtin.c | 157 +++++++++++++++++++++++++++++++--------- 1 file changed, 121 insertions(+), 36 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 3e8c320028d..5e4c55b331c 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -300,11 +300,11 @@ static const struct column col_physicalmemory[] = }; static const struct column col_pnpentity[] = { - { L"Caption", CIM_STRING }, + { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC }, { L"ClassGuid", CIM_STRING|COL_FLAG_DYNAMIC }, { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC }, { L"Manufacturer", CIM_STRING }, - { L"Name", CIM_STRING }, + { L"Name", CIM_STRING|COL_FLAG_DYNAMIC }, }; static const struct column col_printer[] = { @@ -3253,55 +3253,140 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e return status; }
-static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond ) +static WCHAR *get_reg_value( HKEY key, const WCHAR *value ) { - struct record_pnpentity *rec; - enum fill_status status = FILL_STATUS_UNFILTERED; - HDEVINFO device_info_set; - SP_DEVINFO_DATA devinfo = {0}; - DWORD idx; + DWORD size, type; + WCHAR *ret; + + if (RegQueryValueExW( key, value, NULL, &type, NULL, &size ) || type != REG_SZ) return NULL; + size += sizeof(WCHAR); + if ((ret = malloc( size ))) + { + if (RegQueryValueExW( key, value, NULL, NULL, (BYTE *)ret, &size )) + { + free( ret ); + ret = NULL; + } + } + return ret; +}
- device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT ); +static WCHAR *build_pnp_device_id( const WCHAR *class, const WCHAR *product, const WCHAR *instance ) +{ + static const WCHAR fmt[] = L"%s\%s\%s"; + int len = wcslen(class) + 1 + wcslen(product) + 1 + wcslen(instance) + 1 + ARRAY_SIZE(fmt); + WCHAR *ret = malloc( len * sizeof(WCHAR) ); + if (ret) swprintf( ret, len, fmt, class, product, instance ); + return ret; +}
- devinfo.cbSize = sizeof(devinfo); +static struct record_pnpentity *get_pnp_entities( UINT *count ) +{ + struct record_pnpentity *ret = malloc( 16 * sizeof(*ret) ), *tmp; + WCHAR class[MAX_PATH], product[MAX_PATH], instance[MAX_PATH]; + DWORD nb_allocated = 16, i = 0, idx_enum = 0, idx_class = 0, idx_product = 0; + HKEY key_enum, key_class, key_product, key_instance; + LONG res;
- idx = 0; - while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo )) + if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Enum", 0, KEY_ENUMERATE_SUB_KEYS, &key_enum )) + return NULL; + if (!(ret = malloc( nb_allocated * sizeof(*ret) ))) { - /* noop */ + RegCloseKey( key_enum ); + return NULL;; }
- resize_table( table, idx, sizeof(*rec) ); - table->num_rows = 0; - rec = (struct record_pnpentity *)table->data; - - idx = 0; - while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo )) + while (RegEnumKeyW( key_enum, idx_enum++, class, ARRAY_SIZE(class) ) != ERROR_NO_MORE_ITEMS) { - WCHAR device_id[MAX_PATH], guid[GUID_SIZE]; - if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id, - ARRAY_SIZE(device_id), NULL )) + if (!RegOpenKeyExW( key_enum, class, 0, KEY_ENUMERATE_SUB_KEYS, &key_class )) { - StringFromGUID2( &devinfo.ClassGuid, guid, ARRAY_SIZE(guid) ); - rec->caption = L"Wine PnP Device"; - rec->class_guid = wcsdup( wcslwr(guid) ); - rec->device_id = wcsdup( device_id ); - rec->manufacturer = L"The Wine Project"; - rec->name = L"Wine PnP Device"; - - table->num_rows++; - if (!match_row( table, table->num_rows - 1, cond, &status )) + while ((res = RegEnumKeyW( key_class, idx_class++, product, ARRAY_SIZE(product) )) != ERROR_NO_MORE_ITEMS) { - free_row_values( table, table->num_rows - 1 ); - table->num_rows--; + if (!RegOpenKeyExW( key_class, product, 0, KEY_ENUMERATE_SUB_KEYS, &key_product )) + { + while (RegEnumKeyW( key_product, idx_product++, instance, ARRAY_SIZE(instance) ) != ERROR_NO_MORE_ITEMS) + { + if (!RegOpenKeyExW( key_product, instance, 0, KEY_READ, &key_instance )) + { + ret[i].caption = get_reg_value( key_instance, L"DeviceDesc" ); + ret[i].class_guid = wcslwr( get_reg_value( key_instance, L"ClassGUID" ) ); + ret[i].device_id = wcsupr( build_pnp_device_id( class, product, instance ) ); + ret[i].manufacturer = L"The Wine Project"; + ret[i].name = get_reg_value( key_instance, L"DeviceDesc" ); + RegCloseKey( key_instance ); + if (++i > nb_allocated) + { + nb_allocated *= 2; + if ((tmp = realloc( ret, nb_allocated ))) ret = tmp; + else + { + while (--i) + { + free( (void *)ret[i].caption ); + free( (void *)ret[i].class_guid ); + free( (void *)ret[i].device_id ); + free( (void *)ret[i].name ); + } + goto done; + } + } + } + } + RegCloseKey( key_product ); + idx_product = 0; + } } - else - rec++; + RegCloseKey( key_class ); + idx_class = 0; } }
- SetupDiDestroyDeviceInfoList( device_info_set ); +done: + RegCloseKey( key_enum ); + if (!i) + { + free( ret ); + ret = NULL; + } + *count = i; + return ret; +} + +static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond ) +{ + struct record_pnpentity *rec, *entities; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT offset = 0, row = 0, count = 0, i; + + if (!(entities = get_pnp_entities( &count ))) return FILL_STATUS_FAILED; + if (!resize_table( table, count, sizeof(*rec) )) + { + free( entities ); + return FILL_STATUS_FAILED; + } + + for (i = 0; i < count; i++) + { + rec = (struct record_pnpentity *)(table->data + offset); + rec->caption = entities[i].caption; + rec->class_guid = entities[i].class_guid; + rec->device_id = entities[i].device_id; + rec->manufacturer = entities[i].manufacturer; + rec->name = entities[i].name; + rec->service = entities[i].service; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + + TRACE("created %u rows\n", row); + table->num_rows = row;
+ free( entities ); return status; }
From: Hans Leidekker hans@codeweavers.com
--- dlls/wbemprox/builtin.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 5e4c55b331c..a501948eb26 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -305,6 +305,7 @@ static const struct column col_pnpentity[] = { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC }, { L"Manufacturer", CIM_STRING }, { L"Name", CIM_STRING|COL_FLAG_DYNAMIC }, + { L"Service", CIM_STRING|COL_FLAG_DYNAMIC }, }; static const struct column col_printer[] = { @@ -798,6 +799,7 @@ struct record_pnpentity const WCHAR *device_id; const WCHAR *manufacturer; const WCHAR *name; + const WCHAR *service; }; struct record_printer { @@ -3313,6 +3315,7 @@ static struct record_pnpentity *get_pnp_entities( UINT *count ) ret[i].device_id = wcsupr( build_pnp_device_id( class, product, instance ) ); ret[i].manufacturer = L"The Wine Project"; ret[i].name = get_reg_value( key_instance, L"DeviceDesc" ); + ret[i].service = get_reg_value( key_instance, L"Service" ); RegCloseKey( key_instance ); if (++i > nb_allocated) { @@ -3326,6 +3329,7 @@ static struct record_pnpentity *get_pnp_entities( UINT *count ) free( (void *)ret[i].class_guid ); free( (void *)ret[i].device_id ); free( (void *)ret[i].name ); + free( (void *)ret[i].service ); } goto done; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151121
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000006D00F2, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
Report validation errors: d3d11:d3d11 has no test summary line (early exit of the main process?) d3d11:d3d11 has unaccounted for todo messages d3d11:d3d11 returned a non-zero exit code despite reporting no failures wbemprox:query crashed (c0000005)