wbemprox: Retrieve more properties from the SMBIOS table.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3995b5ecf9
commit
7e085d6ee2
|
@ -425,23 +425,23 @@ static const WCHAR prop_workingsetsizeW[] =
|
|||
/* column definitions must be kept in sync with record structures below */
|
||||
static const struct column col_baseboard[] =
|
||||
{
|
||||
{ prop_manufacturerW, CIM_STRING },
|
||||
{ prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_modelW, CIM_STRING },
|
||||
{ prop_nameW, CIM_STRING },
|
||||
{ prop_productW, CIM_STRING },
|
||||
{ prop_serialnumberW, CIM_STRING },
|
||||
{ prop_productW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_serialnumberW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_tagW, CIM_STRING|COL_FLAG_KEY },
|
||||
{ prop_versionW, CIM_STRING }
|
||||
{ prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
|
||||
};
|
||||
static const struct column col_bios[] =
|
||||
{
|
||||
{ prop_descriptionW, CIM_STRING },
|
||||
{ prop_identificationcodeW, CIM_STRING },
|
||||
{ prop_manufacturerW, CIM_STRING },
|
||||
{ prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_nameW, CIM_STRING },
|
||||
{ prop_releasedateW, CIM_DATETIME },
|
||||
{ prop_releasedateW, CIM_DATETIME|COL_FLAG_DYNAMIC },
|
||||
{ prop_serialnumberW, CIM_STRING },
|
||||
{ prop_smbiosbiosversionW, CIM_STRING },
|
||||
{ prop_smbiosbiosversionW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_smbiosmajorversionW, CIM_UINT16, VT_I4 },
|
||||
{ prop_smbiosminorversionW, CIM_UINT16, VT_I4 },
|
||||
{ prop_versionW, CIM_STRING|COL_FLAG_KEY }
|
||||
|
@ -469,12 +469,12 @@ static const struct column col_compsys[] =
|
|||
};
|
||||
static const struct column col_compsysproduct[] =
|
||||
{
|
||||
{ prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY },
|
||||
{ prop_nameW, CIM_STRING|COL_FLAG_KEY },
|
||||
{ prop_identifyingnumberW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
|
||||
{ prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
|
||||
{ prop_skunumberW, CIM_STRING },
|
||||
{ prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_vendorW, CIM_STRING },
|
||||
{ prop_versionW, CIM_STRING|COL_FLAG_KEY }
|
||||
{ prop_vendorW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
|
||||
};
|
||||
static const struct column col_datafile[] =
|
||||
{
|
||||
|
@ -716,10 +716,10 @@ static const struct column col_stdregprov[] =
|
|||
static const struct column col_systemenclosure[] =
|
||||
{
|
||||
{ prop_captionW, CIM_STRING },
|
||||
{ prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY },
|
||||
{ prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC, VT_I4|VT_ARRAY },
|
||||
{ prop_descriptionW, CIM_STRING },
|
||||
{ prop_lockpresentW, CIM_BOOLEAN },
|
||||
{ prop_manufacturerW, CIM_STRING },
|
||||
{ prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
|
||||
{ prop_nameW, CIM_STRING },
|
||||
{ prop_tagW, CIM_STRING },
|
||||
};
|
||||
|
@ -766,8 +766,6 @@ static const WCHAR bios_descriptionW[] =
|
|||
{'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0};
|
||||
static const WCHAR bios_manufacturerW[] =
|
||||
{'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
|
||||
static const WCHAR bios_nameW[] =
|
||||
{'W','I','N','E',' ','B','I','O','S',0};
|
||||
static const WCHAR bios_releasedateW[] =
|
||||
{'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
|
||||
static const WCHAR bios_serialnumberW[] =
|
||||
|
@ -1149,13 +1147,13 @@ struct record_systemsecurity
|
|||
};
|
||||
struct record_systemenclosure
|
||||
{
|
||||
const WCHAR *caption;
|
||||
const WCHAR *caption;
|
||||
const struct array *chassistypes;
|
||||
const WCHAR *description;
|
||||
int lockpresent;
|
||||
const WCHAR *manufacturer;
|
||||
const WCHAR *name;
|
||||
const WCHAR *tag;
|
||||
const WCHAR *description;
|
||||
int lockpresent;
|
||||
const WCHAR *manufacturer;
|
||||
const WCHAR *name;
|
||||
const WCHAR *tag;
|
||||
};
|
||||
struct record_videocontroller
|
||||
{
|
||||
|
@ -1184,15 +1182,6 @@ struct record_videocontroller
|
|||
};
|
||||
#include "poppack.h"
|
||||
|
||||
static const struct record_baseboard data_baseboard[] =
|
||||
{
|
||||
{ baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW }
|
||||
};
|
||||
static const struct record_bios data_bios[] =
|
||||
{
|
||||
{ bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW,
|
||||
bios_smbiosbiosversionW, 1, 0, bios_versionW }
|
||||
};
|
||||
static const struct record_param data_param[] =
|
||||
{
|
||||
{ class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
|
||||
|
@ -1255,18 +1244,6 @@ static const struct array systemenclosure_chassistypes_array =
|
|||
ARRAY_SIZE(systemenclosure_chassistypes),
|
||||
&systemenclosure_chassistypes
|
||||
};
|
||||
static const struct record_systemenclosure data_systemenclosure[] =
|
||||
{
|
||||
{
|
||||
systemenclosure_systemenclosureW,
|
||||
&systemenclosure_chassistypes_array,
|
||||
systemenclosure_systemenclosureW,
|
||||
FALSE,
|
||||
systemenclosure_manufacturerW,
|
||||
systemenclosure_systemenclosureW,
|
||||
systemenclosure_tagW,
|
||||
}
|
||||
};
|
||||
static const struct record_systemsecurity data_systemsecurity[] =
|
||||
{
|
||||
{ security_get_sd, security_set_sd }
|
||||
|
@ -1311,6 +1288,317 @@ static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#include "pshpack1.h"
|
||||
struct smbios_prologue
|
||||
{
|
||||
BYTE calling_method;
|
||||
BYTE major_version;
|
||||
BYTE minor_version;
|
||||
BYTE revision;
|
||||
DWORD length;
|
||||
};
|
||||
|
||||
enum smbios_type
|
||||
{
|
||||
SMBIOS_TYPE_BIOS,
|
||||
SMBIOS_TYPE_SYSTEM,
|
||||
SMBIOS_TYPE_BASEBOARD,
|
||||
SMBIOS_TYPE_CHASSIS,
|
||||
};
|
||||
|
||||
struct smbios_header
|
||||
{
|
||||
BYTE type;
|
||||
BYTE length;
|
||||
WORD handle;
|
||||
};
|
||||
|
||||
struct smbios_baseboard
|
||||
{
|
||||
struct smbios_header hdr;
|
||||
BYTE vendor;
|
||||
BYTE product;
|
||||
BYTE version;
|
||||
BYTE serial;
|
||||
};
|
||||
|
||||
struct smbios_bios
|
||||
{
|
||||
struct smbios_header hdr;
|
||||
BYTE vendor;
|
||||
BYTE version;
|
||||
WORD start;
|
||||
BYTE date;
|
||||
BYTE size;
|
||||
UINT64 characteristics;
|
||||
};
|
||||
|
||||
struct smbios_chassis
|
||||
{
|
||||
struct smbios_header hdr;
|
||||
BYTE vendor;
|
||||
BYTE type;
|
||||
BYTE version;
|
||||
BYTE serial;
|
||||
BYTE asset_tag;
|
||||
};
|
||||
|
||||
struct smbios_system
|
||||
{
|
||||
struct smbios_header hdr;
|
||||
BYTE vendor;
|
||||
BYTE product;
|
||||
BYTE version;
|
||||
BYTE serial;
|
||||
BYTE uuid[16];
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
#define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
|
||||
|
||||
static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
|
||||
{
|
||||
const char *ptr, *start;
|
||||
const struct smbios_prologue *prologue;
|
||||
const struct smbios_header *hdr;
|
||||
|
||||
if (len < sizeof(struct smbios_prologue)) return NULL;
|
||||
prologue = (const struct smbios_prologue *)buf;
|
||||
if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
|
||||
|
||||
start = (const char *)(prologue + 1);
|
||||
hdr = (const struct smbios_header *)start;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
|
||||
|
||||
if (!hdr->length)
|
||||
{
|
||||
WARN( "invalid entry\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hdr->type == type)
|
||||
{
|
||||
if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
|
||||
break;
|
||||
}
|
||||
else /* skip other entries and their strings */
|
||||
{
|
||||
for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
|
||||
{
|
||||
for (; ptr - buf < len; ptr++) if (!*ptr) break;
|
||||
}
|
||||
if (ptr == (const char *)hdr + hdr->length) ptr++;
|
||||
hdr = (const struct smbios_header *)(ptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
static WCHAR *get_smbios_string( BYTE id, const char *buf, UINT offset, UINT buflen )
|
||||
{
|
||||
const char *ptr = buf + offset;
|
||||
UINT i = 0;
|
||||
|
||||
if (!id || offset >= buflen) return NULL;
|
||||
for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
|
||||
{
|
||||
if (++i == id) return heap_strdupAW( ptr );
|
||||
for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static WCHAR *get_baseboard_string( BYTE id, const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_baseboard *baseboard;
|
||||
UINT offset;
|
||||
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BASEBOARD, buf, len ))) return NULL;
|
||||
|
||||
baseboard = (const struct smbios_baseboard *)hdr;
|
||||
offset = (const char *)baseboard - buf + baseboard->hdr.length;
|
||||
return get_smbios_string( id, buf, offset, len );
|
||||
}
|
||||
|
||||
static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_baseboard_string( 1, buf, len );
|
||||
if (!ret) return heap_strdupW( baseboard_manufacturerW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_baseboard_product( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_baseboard_string( 2, buf, len );
|
||||
if (!ret) return heap_strdupW( baseboard_tagW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_baseboard_string( 4, buf, len );
|
||||
if (!ret) return heap_strdupW( baseboard_serialnumberW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_baseboard_version( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_baseboard_string( 3, buf, len );
|
||||
if (!ret) return heap_strdupW( baseboard_versionW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
|
||||
{
|
||||
struct record_baseboard *rec;
|
||||
enum fill_status status = FILL_STATUS_UNFILTERED;
|
||||
UINT row = 0, len;
|
||||
char *buf;
|
||||
|
||||
if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
|
||||
|
||||
len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
|
||||
if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
|
||||
GetSystemFirmwareTable( RSMB, 0, buf, len );
|
||||
|
||||
rec = (struct record_baseboard *)table->data;
|
||||
rec->manufacturer = get_baseboard_manufacturer( buf, len );
|
||||
rec->model = baseboard_tagW;
|
||||
rec->name = baseboard_tagW;
|
||||
rec->product = get_baseboard_product( buf, len );
|
||||
rec->serialnumber = get_baseboard_serialnumber( buf, len );
|
||||
rec->tag = baseboard_tagW;
|
||||
rec->version = get_baseboard_version( buf, len );
|
||||
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
|
||||
else row++;
|
||||
|
||||
heap_free( buf );
|
||||
|
||||
TRACE("created %u rows\n", row);
|
||||
table->num_rows = row;
|
||||
return status;
|
||||
}
|
||||
|
||||
static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
|
||||
if (len < sizeof(*prologue)) return 2;
|
||||
return prologue->major_version;
|
||||
}
|
||||
|
||||
static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
|
||||
if (len < sizeof(*prologue)) return 0;
|
||||
return prologue->minor_version;
|
||||
}
|
||||
|
||||
static WCHAR *get_bios_string( BYTE id, const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_bios *bios;
|
||||
UINT offset;
|
||||
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return NULL;
|
||||
|
||||
bios = (const struct smbios_bios *)hdr;
|
||||
offset = (const char *)bios - buf + bios->hdr.length;
|
||||
return get_smbios_string( id, buf, offset, len );
|
||||
}
|
||||
|
||||
static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_bios_string( 1, buf, len );
|
||||
if (!ret) return heap_strdupW( bios_manufacturerW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *convert_bios_date( const WCHAR *str )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','0','4','u','%','0','2','u','%','0','2','u','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
|
||||
UINT year, month, day, len = lstrlenW( str );
|
||||
const WCHAR *p = str, *q;
|
||||
WCHAR *ret;
|
||||
|
||||
while (len && iswspace( *p )) { p++; len--; }
|
||||
while (len && iswspace( p[len - 1] )) { len--; }
|
||||
|
||||
q = p;
|
||||
while (len && iswdigit( *q )) { q++; len--; };
|
||||
if (q - p != 2 || !len || *q != '/') return NULL;
|
||||
month = (p[0] - '0') * 10 + p[1] - '0';
|
||||
|
||||
p = ++q; len--;
|
||||
while (len && iswdigit( *q )) { q++; len--; };
|
||||
if (q - p != 2 || !len || *q != '/') return NULL;
|
||||
day = (p[0] - '0') * 10 + p[1] - '0';
|
||||
|
||||
p = ++q; len--;
|
||||
while (len && iswdigit( *q )) { q++; len--; };
|
||||
if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
|
||||
else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
|
||||
else return NULL;
|
||||
|
||||
if (!(ret = heap_alloc( sizeof(fmtW) ))) return NULL;
|
||||
swprintf( ret, ARRAY_SIZE(fmtW), fmtW, year, month, day );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_bios_releasedate( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret, *date = get_bios_string( 3, buf, len );
|
||||
if (!date || !(ret = convert_bios_date( date ))) ret = heap_strdupW( bios_releasedateW );
|
||||
heap_free( date );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_bios_string( 2, buf, len );
|
||||
if (!ret) return heap_strdupW( bios_smbiosbiosversionW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum fill_status fill_bios( struct table *table, const struct expr *cond )
|
||||
{
|
||||
struct record_bios *rec;
|
||||
enum fill_status status = FILL_STATUS_UNFILTERED;
|
||||
UINT row = 0, len;
|
||||
char *buf;
|
||||
|
||||
if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
|
||||
|
||||
len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
|
||||
if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
|
||||
GetSystemFirmwareTable( RSMB, 0, buf, len );
|
||||
|
||||
rec = (struct record_bios *)table->data;
|
||||
rec->description = bios_descriptionW;
|
||||
rec->identificationcode = NULL;
|
||||
rec->manufacturer = get_bios_manufacturer( buf, len );
|
||||
rec->name = bios_descriptionW;
|
||||
rec->releasedate = get_bios_releasedate( buf, len );
|
||||
rec->serialnumber = bios_serialnumberW;
|
||||
rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len );
|
||||
rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
|
||||
rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
|
||||
rec->version = bios_versionW;
|
||||
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
|
||||
else row++;
|
||||
|
||||
heap_free( buf );
|
||||
|
||||
TRACE("created %u rows\n", row);
|
||||
table->num_rows = row;
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','c',':',0};
|
||||
|
@ -1476,114 +1764,97 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
|
|||
return status;
|
||||
}
|
||||
|
||||
#include "pshpack1.h"
|
||||
struct smbios_prologue
|
||||
static WCHAR *get_compsysproduct_string( BYTE id, const char *buf, UINT len )
|
||||
{
|
||||
BYTE calling_method;
|
||||
BYTE major_version;
|
||||
BYTE minor_version;
|
||||
BYTE revision;
|
||||
DWORD length;
|
||||
};
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_system *system;
|
||||
UINT offset;
|
||||
|
||||
struct smbios_header
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
|
||||
|
||||
system = (const struct smbios_system *)hdr;
|
||||
offset = (const char *)system - buf + system->hdr.length;
|
||||
return get_smbios_string( id, buf, offset, len );
|
||||
}
|
||||
|
||||
static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
|
||||
{
|
||||
BYTE type;
|
||||
BYTE length;
|
||||
WORD handle;
|
||||
};
|
||||
WCHAR *ret = get_compsysproduct_string( 4, buf, len );
|
||||
if (!ret) return heap_strdupW( compsysproduct_identifyingnumberW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct smbios_system
|
||||
static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
|
||||
{
|
||||
struct smbios_header hdr;
|
||||
BYTE vendor;
|
||||
BYTE product;
|
||||
BYTE version;
|
||||
BYTE serial;
|
||||
BYTE uuid[16];
|
||||
};
|
||||
#include "poppack.h"
|
||||
WCHAR *ret = get_compsysproduct_string( 2, buf, len );
|
||||
if (!ret) return heap_strdupW( compsysproduct_nameW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
|
||||
|
||||
static WCHAR *get_compsysproduct_uuid(void)
|
||||
static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
|
||||
'%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
|
||||
'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
|
||||
static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
ULONG len;
|
||||
char *buf = NULL;
|
||||
const char *ptr, *start;
|
||||
const struct smbios_prologue *prologue;
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_system *system;
|
||||
const BYTE *uuid = NULL;
|
||||
const BYTE *ptr;
|
||||
WCHAR *ret = NULL;
|
||||
|
||||
if ((len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 )) < sizeof(*prologue) ) goto done;
|
||||
if (!(buf = heap_alloc( len ))) goto done;
|
||||
GetSystemFirmwareTable( RSMB, 0, buf, len );
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
|
||||
system = (const struct smbios_system *)hdr;
|
||||
if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
|
||||
|
||||
prologue = (const struct smbios_prologue *)buf;
|
||||
if (prologue->length < sizeof(*hdr)) goto done;
|
||||
start = (const char *)(prologue + 1);
|
||||
hdr = (const struct smbios_header *)start;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (uuid || (const char *)hdr - start >= prologue->length - sizeof(*hdr)) break;
|
||||
if (!hdr->length)
|
||||
{
|
||||
WARN( "invalid entry\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hdr->type)
|
||||
{
|
||||
case 1: /* system entry */
|
||||
if (hdr->length < sizeof(*system) || (const char *)hdr - start + hdr->length > prologue->length) break;
|
||||
system = (const struct smbios_system *)hdr;
|
||||
uuid = system->uuid;
|
||||
break;
|
||||
|
||||
default: /* skip other entries */
|
||||
for (ptr = (const char *)hdr + hdr->length; *ptr; ptr += strlen(ptr) + 1) { /* nothing */ }
|
||||
if (ptr == (const char *)hdr + hdr->length) ptr++;
|
||||
hdr = (const struct smbios_header *)(ptr + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!uuid || !memcmp( uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
|
||||
|
||||
swprintf( ret, 37, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8],
|
||||
uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] );
|
||||
ptr = system->uuid;
|
||||
swprintf( ret, 37, fmtW, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9],
|
||||
ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15] );
|
||||
|
||||
done:
|
||||
heap_free( buf );
|
||||
if (!ret) ret = heap_strdupW( compsysproduct_uuidW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_compsysproduct_string( 1, buf, len );
|
||||
if (!ret) return heap_strdupW( compsysproduct_vendorW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_compsysproduct_string( 3, buf, len );
|
||||
if (!ret) return heap_strdupW( compsysproduct_versionW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
|
||||
{
|
||||
struct record_computersystemproduct *rec;
|
||||
enum fill_status status = FILL_STATUS_UNFILTERED;
|
||||
UINT row = 0;
|
||||
UINT row = 0, len;
|
||||
char *buf;
|
||||
|
||||
if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
|
||||
|
||||
len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
|
||||
if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
|
||||
GetSystemFirmwareTable( RSMB, 0, buf, len );
|
||||
|
||||
rec = (struct record_computersystemproduct *)table->data;
|
||||
rec->identifyingnumber = compsysproduct_identifyingnumberW;
|
||||
rec->name = compsysproduct_nameW;
|
||||
rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
|
||||
rec->name = get_compsysproduct_name( buf, len );
|
||||
rec->skunumber = NULL;
|
||||
rec->uuid = get_compsysproduct_uuid();
|
||||
rec->vendor = compsysproduct_vendorW;
|
||||
rec->version = compsysproduct_versionW;
|
||||
rec->uuid = get_compsysproduct_uuid( buf, len );
|
||||
rec->vendor = get_compsysproduct_vendor( buf, len );
|
||||
rec->version = get_compsysproduct_version( buf, len );
|
||||
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
|
||||
else row++;
|
||||
|
||||
heap_free( buf );
|
||||
|
||||
TRACE("created %u rows\n", row);
|
||||
table->num_rows = row;
|
||||
return status;
|
||||
|
@ -2124,10 +2395,7 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr *
|
|||
rec->index = index;
|
||||
rec->interfacetype = diskdrive_interfacetypeW;
|
||||
rec->manufacturer = diskdrive_manufacturerW;
|
||||
if (type == DRIVE_FIXED)
|
||||
rec->mediatype = diskdrive_mediatype_fixedW;
|
||||
else
|
||||
rec->mediatype = diskdrive_mediatype_removableW;
|
||||
rec->mediatype = (type == DRIVE_FIXED) ? diskdrive_mediatype_fixedW : diskdrive_mediatype_removableW;
|
||||
rec->model = diskdrive_modelW;
|
||||
rec->pnpdevice_id = diskdrive_pnpdeviceidW;
|
||||
rec->serialnumber = diskdrive_serialW;
|
||||
|
@ -3551,6 +3819,110 @@ static enum fill_status fill_sid( struct table *table, const struct expr *cond )
|
|||
return FILL_STATUS_FILTERED;
|
||||
}
|
||||
|
||||
static WCHAR *get_systemenclosure_string( BYTE id, const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_chassis *chassis;
|
||||
UINT offset;
|
||||
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len ))) return NULL;
|
||||
|
||||
chassis = (const struct smbios_chassis *)hdr;
|
||||
offset = (const char *)chassis - buf + chassis->hdr.length;
|
||||
return get_smbios_string( id, buf, offset, len );
|
||||
}
|
||||
|
||||
static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
|
||||
{
|
||||
WCHAR *ret = get_systemenclosure_string( 1, buf, len );
|
||||
if (!ret) return heap_strdupW( systemenclosure_manufacturerW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_systemenclosure_lockpresent( const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_chassis *chassis;
|
||||
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
|
||||
|
||||
chassis = (const struct smbios_chassis *)hdr;
|
||||
return (chassis->type & 0x80) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct array *dup_array( const struct array *src )
|
||||
{
|
||||
struct array *dst;
|
||||
if (!(dst = heap_alloc( sizeof(*dst) ))) return NULL;
|
||||
if (!(dst->ptr = heap_alloc( src->count * src->elem_size )))
|
||||
{
|
||||
heap_free( dst );
|
||||
return NULL;
|
||||
}
|
||||
memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
|
||||
dst->elem_size = src->elem_size;
|
||||
dst->count = src->count;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
|
||||
{
|
||||
const struct smbios_header *hdr;
|
||||
const struct smbios_chassis *chassis;
|
||||
struct array *ret = NULL;
|
||||
UINT16 *types;
|
||||
|
||||
if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
|
||||
chassis = (const struct smbios_chassis *)hdr;
|
||||
|
||||
if (!(ret = heap_alloc( sizeof(*ret) ))) goto done;
|
||||
if (!(types = heap_alloc( sizeof(*types) )))
|
||||
{
|
||||
heap_free( ret );
|
||||
goto done;
|
||||
}
|
||||
types[0] = chassis->type & ~0x80;
|
||||
|
||||
ret->elem_size = sizeof(*types);
|
||||
ret->count = 1;
|
||||
ret->ptr = types;
|
||||
|
||||
done:
|
||||
if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
|
||||
{
|
||||
struct record_systemenclosure *rec;
|
||||
enum fill_status status = FILL_STATUS_UNFILTERED;
|
||||
UINT row = 0, len;
|
||||
char *buf;
|
||||
|
||||
if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
|
||||
|
||||
len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
|
||||
if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
|
||||
GetSystemFirmwareTable( RSMB, 0, buf, len );
|
||||
|
||||
rec = (struct record_systemenclosure *)table->data;
|
||||
rec->caption = systemenclosure_systemenclosureW;
|
||||
rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
|
||||
rec->description = systemenclosure_systemenclosureW;
|
||||
rec->lockpresent = get_systemenclosure_lockpresent( buf, len );
|
||||
rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
|
||||
rec->name = systemenclosure_systemenclosureW;
|
||||
rec->tag = systemenclosure_tagW;
|
||||
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
|
||||
else row++;
|
||||
|
||||
heap_free( buf );
|
||||
|
||||
TRACE("created %u rows\n", row);
|
||||
table->num_rows = row;
|
||||
return status;
|
||||
}
|
||||
|
||||
static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
|
||||
{
|
||||
HDC hdc = GetDC( NULL );
|
||||
|
@ -3665,41 +4037,45 @@ done:
|
|||
return status;
|
||||
}
|
||||
|
||||
#define C(c) sizeof(c)/sizeof(c[0]), c
|
||||
#define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
|
||||
static struct table builtin_classes[] =
|
||||
{
|
||||
{ class_baseboardW, ARRAY_SIZE(col_baseboard), col_baseboard, ARRAY_SIZE(data_baseboard), 0, (BYTE *)data_baseboard },
|
||||
{ class_biosW, ARRAY_SIZE(col_bios), col_bios, ARRAY_SIZE(data_bios), 0, (BYTE *)data_bios },
|
||||
{ class_cdromdriveW, ARRAY_SIZE(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive },
|
||||
{ class_compsysW, ARRAY_SIZE(col_compsys), col_compsys, 0, 0, NULL, fill_compsys },
|
||||
{ class_compsysproductW, ARRAY_SIZE(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct },
|
||||
{ class_datafileW, ARRAY_SIZE(col_datafile), col_datafile, 0, 0, NULL, fill_datafile },
|
||||
{ class_desktopmonitorW, ARRAY_SIZE(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor },
|
||||
{ class_directoryW, ARRAY_SIZE(col_directory), col_directory, 0, 0, NULL, fill_directory },
|
||||
{ class_diskdriveW, ARRAY_SIZE(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive },
|
||||
{ class_diskpartitionW, ARRAY_SIZE(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition },
|
||||
{ class_ip4routetableW, ARRAY_SIZE(col_ip4routetable), col_ip4routetable, 0, 0, NULL, fill_ip4routetable },
|
||||
{ class_logicaldiskW, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
|
||||
{ class_logicaldisk2W, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
|
||||
{ class_networkadapterW, ARRAY_SIZE(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter },
|
||||
{ class_networkadapterconfigW, ARRAY_SIZE(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig },
|
||||
{ class_osW, ARRAY_SIZE(col_os), col_os, 0, 0, NULL, fill_os },
|
||||
{ class_paramsW, ARRAY_SIZE(col_param), col_param, ARRAY_SIZE(data_param), 0, (BYTE *)data_param },
|
||||
{ class_physicalmediaW, ARRAY_SIZE(col_physicalmedia), col_physicalmedia, ARRAY_SIZE(data_physicalmedia), 0, (BYTE *)data_physicalmedia },
|
||||
{ class_physicalmemoryW, ARRAY_SIZE(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory },
|
||||
{ class_pnpentityW, ARRAY_SIZE(col_pnpentity), col_pnpentity, 0, 0, NULL, fill_pnpentity },
|
||||
{ class_printerW, ARRAY_SIZE(col_printer), col_printer, 0, 0, NULL, fill_printer },
|
||||
{ class_processW, ARRAY_SIZE(col_process), col_process, 0, 0, NULL, fill_process },
|
||||
{ class_processorW, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
|
||||
{ class_processor2W, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
|
||||
{ class_qualifiersW, ARRAY_SIZE(col_qualifier), col_qualifier, ARRAY_SIZE(data_qualifier), 0, (BYTE *)data_qualifier },
|
||||
{ class_serviceW, ARRAY_SIZE(col_service), col_service, 0, 0, NULL, fill_service },
|
||||
{ class_sidW, ARRAY_SIZE(col_sid), col_sid, 0, 0, NULL, fill_sid },
|
||||
{ class_sounddeviceW, ARRAY_SIZE(col_sounddevice), col_sounddevice, ARRAY_SIZE(data_sounddevice), 0, (BYTE *)data_sounddevice },
|
||||
{ class_stdregprovW, ARRAY_SIZE(col_stdregprov), col_stdregprov, ARRAY_SIZE(data_stdregprov), 0, (BYTE *)data_stdregprov },
|
||||
{ class_systemsecurityW, ARRAY_SIZE(col_systemsecurity), col_systemsecurity, ARRAY_SIZE(data_systemsecurity), 0, (BYTE *)data_systemsecurity },
|
||||
{ class_systemenclosureW, ARRAY_SIZE(col_systemenclosure), col_systemenclosure, ARRAY_SIZE(data_systemenclosure), 0, (BYTE *)data_systemenclosure },
|
||||
{ class_videocontrollerW, ARRAY_SIZE(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller }
|
||||
{ class_baseboardW, C(col_baseboard), 0, 0, NULL, fill_baseboard },
|
||||
{ class_biosW, C(col_bios), 0, 0, NULL, fill_bios },
|
||||
{ class_cdromdriveW, C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
|
||||
{ class_compsysW, C(col_compsys), 0, 0, NULL, fill_compsys },
|
||||
{ class_compsysproductW, C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
|
||||
{ class_datafileW, C(col_datafile), 0, 0, NULL, fill_datafile },
|
||||
{ class_desktopmonitorW, C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
|
||||
{ class_directoryW, C(col_directory), 0, 0, NULL, fill_directory },
|
||||
{ class_diskdriveW, C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
|
||||
{ class_diskpartitionW, C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
|
||||
{ class_ip4routetableW, C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
|
||||
{ class_logicaldiskW, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
|
||||
{ class_logicaldisk2W, C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
|
||||
{ class_networkadapterW, C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
|
||||
{ class_networkadapterconfigW, C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
|
||||
{ class_osW, C(col_os), 0, 0, NULL, fill_os },
|
||||
{ class_paramsW, C(col_param), D(data_param) },
|
||||
{ class_physicalmediaW, C(col_physicalmedia), D(data_physicalmedia) },
|
||||
{ class_physicalmemoryW, C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
|
||||
{ class_pnpentityW, C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
|
||||
{ class_printerW, C(col_printer), 0, 0, NULL, fill_printer },
|
||||
{ class_processW, C(col_process), 0, 0, NULL, fill_process },
|
||||
{ class_processorW, C(col_processor), 0, 0, NULL, fill_processor },
|
||||
{ class_processor2W, C(col_processor), 0, 0, NULL, fill_processor },
|
||||
{ class_qualifiersW, C(col_qualifier), D(data_qualifier) },
|
||||
{ class_serviceW, C(col_service), 0, 0, NULL, fill_service },
|
||||
{ class_sidW, C(col_sid), 0, 0, NULL, fill_sid },
|
||||
{ class_sounddeviceW, C(col_sounddevice), D(data_sounddevice) },
|
||||
{ class_stdregprovW, C(col_stdregprov), D(data_stdregprov) },
|
||||
{ class_systemsecurityW, C(col_systemsecurity), D(data_systemsecurity) },
|
||||
{ class_systemenclosureW, C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
|
||||
{ class_videocontrollerW, C(col_videocontroller), 0, 0, NULL, fill_videocontroller }
|
||||
};
|
||||
#undef C
|
||||
#undef D
|
||||
|
||||
void init_table_list( void )
|
||||
{
|
||||
|
|
|
@ -244,6 +244,16 @@ static inline WCHAR *heap_strdupW( const WCHAR *src )
|
|||
return dst;
|
||||
}
|
||||
|
||||
static inline WCHAR *heap_strdupAW( const char *src )
|
||||
{
|
||||
int len;
|
||||
WCHAR *dst;
|
||||
if (!src) return NULL;
|
||||
len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 );
|
||||
if ((dst = heap_alloc( len * sizeof(*dst) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len );
|
||||
return dst;
|
||||
}
|
||||
|
||||
static const WCHAR class_processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
|
||||
static const WCHAR class_serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e',0};
|
||||
static const WCHAR class_stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
|
||||
|
|
Loading…
Reference in New Issue