Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wbemprox/builtin.c | 61 +++++++++++++++++++----------------
dlls/wbemprox/tests/query.c | 63 ++++++++++++++++++++++++++++++++-----
2 files changed, 90 insertions(+), 34 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 03f6e62562..d2b7dc116f 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -1365,38 +1365,47 @@ static UINT get_processor_count(void)
return info.NumberOfProcessors;
}
-static UINT get_logical_processor_count( UINT *num_cores )
+static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
{
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info;
- UINT i, j, count = 0;
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
+ UINT core_relation_count = 0, package_relation_count = 0;
NTSTATUS status;
- ULONG len;
+ ULONG len, offset = 0;
+ BOOL smt_enabled = FALSE;
+ DWORD all;
- if (num_cores) *num_cores = get_processor_count();
- status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len );
+ if (num_packages) *num_packages = 1;
+ status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
- if (!(info = heap_alloc( len ))) return get_processor_count();
- status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len );
+ if (!(buf = heap_alloc( len ))) return get_processor_count();
+ status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
if (status != STATUS_SUCCESS)
{
- heap_free( info );
+ heap_free( buf );
return get_processor_count();
}
- if (num_cores) *num_cores = 0;
- for (i = 0; i < len / sizeof(*info); i++)
+
+ while (offset < len)
{
- if (info[i].Relationship == RelationProcessorCore)
+ entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
+
+ if (entry->Relationship == RelationProcessorCore)
{
- for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++;
+ core_relation_count++;
+ if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
}
- else if (info[i].Relationship == RelationProcessorPackage && num_cores)
+ else if (entry->Relationship == RelationProcessorPackage)
{
- for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++;
+ package_relation_count++;
}
+ offset += entry->Size;
}
- heap_free( info );
- return count;
+
+ heap_free( buf );
+ if (num_physical) *num_physical = core_relation_count;
+ if (num_packages) *num_packages = package_relation_count;
+ return smt_enabled ? core_relation_count * 2 : core_relation_count;
}
static UINT64 get_total_physical_memory(void)
@@ -1460,8 +1469,7 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
rec->manufacturer = compsys_manufacturerW;
rec->model = compsys_modelW;
rec->name = get_computername();
- rec->num_logical_processors = get_logical_processor_count( NULL );
- rec->num_processors = get_processor_count();
+ rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
rec->total_physical_memory = get_total_physical_memory();
rec->username = get_username();
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
@@ -2981,10 +2989,12 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
static const WCHAR fmtW[] = {'C','P','U','%','u',0};
WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
struct record_processor *rec;
- UINT i, offset = 0, num_rows = 0, num_cores, num_logical_processors, count = get_processor_count();
+ UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
enum fill_status status = FILL_STATUS_UNFILTERED;
- if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED;
+ num_logical = get_logical_processor_count( &num_physical, &num_packages );
+
+ if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
get_processor_caption( caption );
get_processor_id( processor_id );
@@ -2992,10 +3002,7 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
get_processor_name( name );
get_processor_version( version );
- num_logical_processors = get_logical_processor_count( &num_cores ) / count;
- num_cores /= count;
-
- for (i = 0; i < count; i++)
+ for (i = 0; i < num_packages; i++)
{
rec = (struct record_processor *)(table->data + offset);
rec->addresswidth = get_osarchitecture() == os_32bitW ? 32 : 64;
@@ -3012,8 +3019,8 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
rec->manufacturer = heap_strdupW( manufacturer );
rec->maxclockspeed = get_processor_maxclockspeed( i );
rec->name = heap_strdupW( name );
- rec->num_cores = num_cores;
- rec->num_logical_processors = num_logical_processors;
+ rec->num_cores = num_physical / num_packages;
+ rec->num_logical_processors = num_logical / num_packages;
rec->processor_id = heap_strdupW( processor_id );
rec->processortype = 3; /* central processor */
rec->revision = get_processor_revision();
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index 82195ebedd..ae0106a341 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -529,12 +529,16 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
static const WCHAR modelW[] = {'M','o','d','e','l',0};
static const WCHAR nameW[] = {'N','a','m','e',0};
static const WCHAR usernameW[] = {'U','s','e','r','N','a','m','e',0};
+ static const WCHAR numprocessorsW[] =
+ {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
+ static const WCHAR numlogicalprocessorsW[] =
+ {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
static const WCHAR queryW[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
IEnumWbemClassObject *result;
- IWbemClassObject *service;
+ IWbemClassObject *obj;
VARIANT value;
CIMTYPE type;
HRESULT hr;
@@ -565,17 +569,17 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
goto out;
}
- hr = IEnumWbemClassObject_Next( result, 10000, 1, &service, &count );
+ hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
ok( hr == S_OK, "got %08x\n", hr );
type = 0xdeadbeef;
VariantInit( &value );
- hr = IWbemClassObject_Get( service, memorytypeW, 0, &value, &type, NULL );
+ hr = IWbemClassObject_Get( obj, memorytypeW, 0, &value, &type, NULL );
ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
type = 0xdeadbeef;
VariantInit( &value );
- hr = IWbemClassObject_Get( service, modelW, 0, &value, &type, NULL );
+ hr = IWbemClassObject_Get( obj, modelW, 0, &value, &type, NULL );
ok( hr == S_OK, "failed to get model %08x\n", hr );
ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
@@ -584,7 +588,7 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
type = 0xdeadbeef;
VariantInit( &value );
- hr = IWbemClassObject_Get( service, nameW, 0, &value, &type, NULL );
+ hr = IWbemClassObject_Get( obj, nameW, 0, &value, &type, NULL );
ok( hr == S_OK, "failed to get computer name %08x\n", hr );
ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
@@ -593,14 +597,33 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
type = 0xdeadbeef;
VariantInit( &value );
- hr = IWbemClassObject_Get( service, usernameW, 0, &value, &type, NULL );
+ hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &value, &type, NULL );
+ ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+ if (hr == S_OK)
+ {
+ ok( V_VT( &value ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &value ) );
+ ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+ trace( "numlogicalprocessors %u\n", V_I4( &value ) );
+ }
+
+ type = 0xdeadbeef;
+ VariantInit( &value );
+ hr = IWbemClassObject_Get( obj, numprocessorsW, 0, &value, &type, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( V_VT( &value ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &value ) );
+ ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+ trace( "numprocessors %u\n", V_I4( &value ) );
+
+ type = 0xdeadbeef;
+ VariantInit( &value );
+ hr = IWbemClassObject_Get( obj, usernameW, 0, &value, &type, NULL );
ok( hr == S_OK, "failed to get computer name %08x\n", hr );
ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
VariantClear( &value );
- IWbemClassObject_Release( service );
+ IWbemClassObject_Release( obj );
IEnumWbemClassObject_Release( result );
out:
SysFreeString( query );
@@ -1563,6 +1586,10 @@ static void test_Win32_Processor( IWbemServices *services )
{'M','a','n','u','f','a','c','t','u','r','e','r',0};
static const WCHAR nameW[] =
{'N','a','m','e',0};
+ static const WCHAR numcoresW[] =
+ {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
+ static const WCHAR numlogicalprocessorsW[] =
+ {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
static const WCHAR processoridW[] =
{'P','r','o','c','e','s','s','o','r','I','d',0};
static const WCHAR revisionW[] =
@@ -1665,6 +1692,28 @@ static void test_Win32_Processor( IWbemServices *services )
trace( "version %s\n", wine_dbgstr_w(V_BSTR( &val )) );
VariantClear( &val );
+ type = 0xdeadbeef;
+ VariantInit( &val );
+ hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &val, &type, NULL );
+ ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+ if (hr == S_OK)
+ {
+ ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
+ ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+ trace( "numlogicalprocessors %u\n", V_I4( &val ) );
+ }
+
+ type = 0xdeadbeef;
+ VariantInit( &val );
+ hr = IWbemClassObject_Get( obj, numcoresW, 0, &val, &type, NULL );
+ ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+ if (hr == S_OK)
+ {
+ ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
+ ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+ trace( "numcores %u\n", V_I4( &val ) );
+ }
+
IWbemClassObject_Release( obj );
}
--
2.20.1