forked from Mirrors/wine-wine
wbemprox: Create one processor object per package.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>stable
parent
f2e1c51422
commit
cee8986529
|
@ -1365,38 +1365,47 @@ static UINT get_processor_count(void)
|
||||||
return info.NumberOfProcessors;
|
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;
|
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
|
||||||
UINT i, j, count = 0;
|
UINT core_relation_count = 0, package_relation_count = 0;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG len;
|
ULONG len, offset = 0;
|
||||||
|
BOOL smt_enabled = FALSE;
|
||||||
|
DWORD all;
|
||||||
|
|
||||||
if (num_cores) *num_cores = get_processor_count();
|
if (num_packages) *num_packages = 1;
|
||||||
status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len );
|
status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
|
||||||
if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
|
if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
|
||||||
|
|
||||||
if (!(info = heap_alloc( len ))) return get_processor_count();
|
if (!(buf = heap_alloc( len ))) return get_processor_count();
|
||||||
status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len );
|
status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
heap_free( info );
|
heap_free( buf );
|
||||||
return get_processor_count();
|
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)
|
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->manufacturer = compsys_manufacturerW;
|
||||||
rec->model = compsys_modelW;
|
rec->model = compsys_modelW;
|
||||||
rec->name = get_computername();
|
rec->name = get_computername();
|
||||||
rec->num_logical_processors = get_logical_processor_count( NULL );
|
rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
|
||||||
rec->num_processors = get_processor_count();
|
|
||||||
rec->total_physical_memory = get_total_physical_memory();
|
rec->total_physical_memory = get_total_physical_memory();
|
||||||
rec->username = get_username();
|
rec->username = get_username();
|
||||||
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
|
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};
|
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];
|
WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
|
||||||
struct record_processor *rec;
|
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;
|
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_caption( caption );
|
||||||
get_processor_id( processor_id );
|
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_name( name );
|
||||||
get_processor_version( version );
|
get_processor_version( version );
|
||||||
|
|
||||||
num_logical_processors = get_logical_processor_count( &num_cores ) / count;
|
for (i = 0; i < num_packages; i++)
|
||||||
num_cores /= count;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
rec = (struct record_processor *)(table->data + offset);
|
rec = (struct record_processor *)(table->data + offset);
|
||||||
rec->addresswidth = get_osarchitecture() == os_32bitW ? 32 : 64;
|
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->manufacturer = heap_strdupW( manufacturer );
|
||||||
rec->maxclockspeed = get_processor_maxclockspeed( i );
|
rec->maxclockspeed = get_processor_maxclockspeed( i );
|
||||||
rec->name = heap_strdupW( name );
|
rec->name = heap_strdupW( name );
|
||||||
rec->num_cores = num_cores;
|
rec->num_cores = num_physical / num_packages;
|
||||||
rec->num_logical_processors = num_logical_processors;
|
rec->num_logical_processors = num_logical / num_packages;
|
||||||
rec->processor_id = heap_strdupW( processor_id );
|
rec->processor_id = heap_strdupW( processor_id );
|
||||||
rec->processortype = 3; /* central processor */
|
rec->processortype = 3; /* central processor */
|
||||||
rec->revision = get_processor_revision();
|
rec->revision = get_processor_revision();
|
||||||
|
|
|
@ -529,12 +529,16 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
|
||||||
static const WCHAR modelW[] = {'M','o','d','e','l',0};
|
static const WCHAR modelW[] = {'M','o','d','e','l',0};
|
||||||
static const WCHAR nameW[] = {'N','a','m','e',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 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[] =
|
static const WCHAR queryW[] =
|
||||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
|
{'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};
|
'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
|
||||||
BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
|
BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
|
||||||
IEnumWbemClassObject *result;
|
IEnumWbemClassObject *result;
|
||||||
IWbemClassObject *service;
|
IWbemClassObject *obj;
|
||||||
VARIANT value;
|
VARIANT value;
|
||||||
CIMTYPE type;
|
CIMTYPE type;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -565,17 +569,17 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
|
||||||
goto out;
|
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 );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
type = 0xdeadbeef;
|
type = 0xdeadbeef;
|
||||||
VariantInit( &value );
|
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 );
|
ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
|
||||||
|
|
||||||
type = 0xdeadbeef;
|
type = 0xdeadbeef;
|
||||||
VariantInit( &value );
|
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( 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( 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( type == CIM_STRING, "unexpected type 0x%x\n", type );
|
||||||
|
@ -584,7 +588,7 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
|
||||||
|
|
||||||
type = 0xdeadbeef;
|
type = 0xdeadbeef;
|
||||||
VariantInit( &value );
|
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( 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( 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( type == CIM_STRING, "unexpected type 0x%x\n", type );
|
||||||
|
@ -593,14 +597,33 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
|
||||||
|
|
||||||
type = 0xdeadbeef;
|
type = 0xdeadbeef;
|
||||||
VariantInit( &value );
|
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( 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( 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( 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) );
|
ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
|
||||||
VariantClear( &value );
|
VariantClear( &value );
|
||||||
|
|
||||||
IWbemClassObject_Release( service );
|
IWbemClassObject_Release( obj );
|
||||||
IEnumWbemClassObject_Release( result );
|
IEnumWbemClassObject_Release( result );
|
||||||
out:
|
out:
|
||||||
SysFreeString( query );
|
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};
|
{'M','a','n','u','f','a','c','t','u','r','e','r',0};
|
||||||
static const WCHAR nameW[] =
|
static const WCHAR nameW[] =
|
||||||
{'N','a','m','e',0};
|
{'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[] =
|
static const WCHAR processoridW[] =
|
||||||
{'P','r','o','c','e','s','s','o','r','I','d',0};
|
{'P','r','o','c','e','s','s','o','r','I','d',0};
|
||||||
static const WCHAR revisionW[] =
|
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 )) );
|
trace( "version %s\n", wine_dbgstr_w(V_BSTR( &val )) );
|
||||||
VariantClear( &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 );
|
IWbemClassObject_Release( obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue