diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 8c4ebe44b00..75cdfc3ba3d 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -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 ) { diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 799bc80050b..c1b1ae86794 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -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};