wbemprox: Retrieve the system UUID 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:
Hans Leidekker 2019-07-03 12:38:30 +02:00 committed by Alexandre Julliard
parent 4ed190e8ac
commit ea3caa2d83
1 changed files with 83 additions and 41 deletions

View File

@ -1493,52 +1493,94 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
return status; return status;
} }
#include "pshpack1.h"
struct smbios_prologue
{
BYTE calling_method;
BYTE major_version;
BYTE minor_version;
BYTE revision;
DWORD length;
};
struct smbios_header
{
BYTE type;
BYTE length;
WORD handle;
};
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 WCHAR *get_compsysproduct_uuid(void) static WCHAR *get_compsysproduct_uuid(void)
{ {
#ifdef __APPLE__ static const WCHAR fmtW[] =
unsigned char uuid[16]; {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
const struct timespec timeout = {1, 0}; '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
if (!gethostuuid( uuid, &timeout )) '%','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};
static const WCHAR fmtW[] = ULONG len;
{'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-', char *buf = NULL;
'%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X', const char *ptr, *start;
'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0}; const struct smbios_prologue *prologue;
WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) ); const struct smbios_header *hdr;
if (!ret) return NULL; const struct smbios_system *system;
sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], const BYTE *uuid = NULL;
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ); WCHAR *ret = NULL;
return ret;
}
#endif
#ifdef __linux__
int file;
if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1)
{
unsigned char buf[32];
if (read( file, buf, sizeof(buf) ) == sizeof(buf))
{
unsigned int i, j;
WCHAR *ret, *p;
close( file ); if ((len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 )) < sizeof(*prologue) ) goto done;
if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL; if (!(buf = heap_alloc( len ))) goto done;
for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] ); GetSystemFirmwareTable( RSMB, 0, buf, len );
p[8] = '-';
for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] ); prologue = (const struct smbios_prologue *)buf;
p[13] = '-'; if (prologue->length < sizeof(*hdr)) goto done;
for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] ); start = (const char *)(prologue + 1);
p[18] = '-'; hdr = (const struct smbios_header *)start;
for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
p[23] = '-'; for (;;)
for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] ); {
ret[i] = 0; if (uuid || (const char *)hdr - start >= prologue->length - sizeof(*hdr)) break;
return ret; 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;
} }
close( file );
} }
#endif if (!uuid || !memcmp( uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
return heap_strdupW( compsysproduct_uuidW );
sprintfW( ret, 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] );
done:
heap_free( buf );
if (!ret) ret = heap_strdupW( compsysproduct_uuidW );
return ret;
} }
static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond ) static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )