-- v2: wbemprox: Implement Win32_CacheMemory table.
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..55a243f1e08 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 ) +{ + enum fill_status status = FILL_STATUS_UNFILTERED; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info; + UINT i, idx, offset = 0, row_count = 0; + struct record_cache_memory *rec; + ULONG64 cache_size[16] = { 0 }; + char *buffer = NULL; + DWORD size = 1024; + WCHAR str[64]; + + while (1) + { + buffer = realloc( buffer, size ); + if (GetLogicalProcessorInformationEx( RelationCache, (void *)buffer, &size )) break; + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + free( buffer ); + return FILL_STATUS_FAILED; + } + } + + info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)buffer; + while ((char *)info != buffer + size) + { + 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( buffer ); + 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( buffer ); + 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 );
v2: - fix processor info buffer freeing; - table fields formatting.
This merge request was approved by Hans Leidekker.