From: Paul Gofman pgofman@codeweavers.com
--- dlls/wbemprox/builtin.c | 96 +++++++++++++++++++++++++++++++++++++ dlls/wbemprox/tests/query.c | 34 +++++++++++++ 2 files changed, 130 insertions(+)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 2e3c3ce041e..e3a54bda571 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -82,6 +82,18 @@ static const struct column col_bios[] = { L"SystemBiosMinorVersion", CIM_UINT8 }, { L"Version", CIM_STRING|COL_FLAG_KEY }, }; +static const struct column col_cache_memory[] = +{ + { L"BlockSize", CIM_UINT64 }, + { L"CacheSpeed", CIM_UINT32 }, + { L"CacheType", CIM_UINT16 }, + { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC }, + { L"InstalledSize", CIM_UINT32 }, + { L"Level", CIM_UINT16 }, + { L"MaxCacheSize", CIM_UINT32 }, + { L"NumberOfBlocks", CIM_UINT64 }, + { L"Status", CIM_STRING }, +}; static const struct column col_cdromdrive[] = { { L"DeviceId", CIM_STRING|COL_FLAG_KEY }, @@ -587,6 +599,18 @@ struct record_bios UINT8 systembiosminorversion; const WCHAR *version; }; +struct record_cache_memory +{ + UINT64 block_size; + UINT32 cache_speed; + UINT16 cache_type; + const WCHAR *device_id; + UINT32 installed_size; + UINT16 level; + UINT32 max_cache_size; + UINT64 number_of_blocks; + const WCHAR *status; +}; struct record_cdromdrive { const WCHAR *device_id; @@ -3635,6 +3659,77 @@ static UINT get_processor_maxclockspeed( UINT index ) return ret; }
+static enum fill_status fill_cache_memory( struct table *table, const struct expr *cond ) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info = NULL, *info_end; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT i, idx, offset = 0, row_count = 0; + struct record_cache_memory *rec; + ULONG64 cache_size[16] = { 0 }; + DWORD size = 1024; + WCHAR str[64]; + + size = 1024; + while (1) + { + info = realloc( info, size ); + if (GetLogicalProcessorInformationEx( RelationCache, info, &size )) break; + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + free( info ); + return FILL_STATUS_FAILED; + } + } + + info_end = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)info + size); + while (info != info_end) + { + if (info->Cache.Level < ARRAY_SIZE(cache_size) && info->Cache.CacheSize) + { + if (!cache_size[info->Cache.Level]) ++row_count; + cache_size[info->Cache.Level] += info->Cache.CacheSize; + } + info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)info + info->Size); + } + + if (!resize_table( table, row_count, sizeof(*rec) )) + { + free( info ); + return FILL_STATUS_FAILED; + } + + row_count = 0; + idx = 0; + for (i = 0; i < ARRAY_SIZE(cache_size); ++i) + { + if (!cache_size[i]) continue; + rec = (struct record_cache_memory *)(table->data + offset); + rec->block_size = 1024; + rec->cache_speed = 1; + rec->cache_type = 5; + rec->installed_size = cache_size[i] / rec->block_size; + rec->level = i + 2; + rec->max_cache_size = rec->installed_size; + rec->number_of_blocks = rec->installed_size; + swprintf( str, sizeof(str), L"Cache Memory %u", idx ); + rec->device_id = wcsdup( str ); + rec->status = L"OK"; + if (!match_row( table, idx, cond, &status )) + { + free_row_values( table, idx ); + ++idx; + continue; + } + offset += sizeof(*rec); + ++idx; + ++row_count; + } + TRACE("created %u rows\n", row_count); + table->num_rows = row_count; + free( info ); + return status; +} + static enum fill_status fill_processor( struct table *table, const struct expr *cond ) { WCHAR device_id[14], processor_id[17], version[50]; @@ -4572,6 +4667,7 @@ static struct table cimv2_builtin_classes[] = { L"SystemRestore", C(col_sysrestore), D(data_sysrestore) }, { L"Win32_BIOS", C(col_bios), 0, 0, NULL, fill_bios }, { L"Win32_BaseBoard", C(col_baseboard), 0, 0, NULL, fill_baseboard }, + { L"Win32_CacheMemory", C(col_cache_memory), 0, 0, NULL, fill_cache_memory }, { L"Win32_CDROMDrive", C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive }, { L"Win32_ComputerSystem", C(col_compsys), 0, 0, NULL, fill_compsys }, { L"Win32_ComputerSystemProduct", C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct }, diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index 1c6530a5b24..7a6e0231316 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -1873,6 +1873,39 @@ static void test_Win32_Processor( IWbemServices *services ) SysFreeString( wql ); }
+static void test_Win32_CacheMemory( IWbemServices *services ) +{ + BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( L"SELECT * FROM Win32_CacheMemory" ); + IEnumWbemClassObject *result; + IWbemClassObject *obj; + DWORD count; + HRESULT hr; + + hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result ); + ok( hr == S_OK, "got %#lx\n", hr ); + + for (;;) + { + hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count ); + if (hr != S_OK) break; + + check_property( obj, L"BlockSize", VT_BSTR, CIM_UINT64 ); + check_property( obj, L"CacheSpeed", VT_I4, CIM_UINT32 ); + check_property( obj, L"CacheType", VT_I4, CIM_UINT16 ); + check_property( obj, L"DeviceID", VT_BSTR, CIM_STRING ); + check_property( obj, L"InstalledSize", VT_I4, CIM_UINT32 ); + check_property( obj, L"Level", VT_I4, CIM_UINT16 ); + check_property( obj, L"MaxCacheSize", VT_I4, CIM_UINT32 ); + check_property( obj, L"NumberOfBlocks", VT_BSTR, CIM_UINT64 ); + check_property( obj, L"Status", VT_BSTR, CIM_STRING ); + IWbemClassObject_Release( obj ); + } + + IEnumWbemClassObject_Release( result ); + SysFreeString( query ); + SysFreeString( wql ); +} + static void test_Win32_VideoController( IWbemServices *services ) { BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( L"SELECT * FROM Win32_VideoController" ); @@ -2552,6 +2585,7 @@ START_TEST(query) test_StdRegProv( services ); test_SystemSecurity( services ); test_Win32_Baseboard( services ); + test_Win32_CacheMemory( services ); test_Win32_ComputerSystem( services ); test_Win32_ComputerSystemProduct( services ); test_Win32_Bios( services );
Used by this utility: https://github.com/wadarochi/hwinfo (which is used, in particular, by Marvel Rivals' launcher).
For some reason no table rows are returned on Testbot machines (maybe SMBios table it is based on Windows is not available??), but I do have 3 levels of cache on my local Windows 11 and the filled in values are based on what I see there.