Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wbemprox/builtin.c | 124 +++++++++++++++++++++++++++-------------
1 file changed, 83 insertions(+), 41 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 6c56d0d70a..6302cf574d 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -1493,52 +1493,94 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
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)
{
-#ifdef __APPLE__
- unsigned char uuid[16];
- const struct timespec timeout = {1, 0};
- if (!gethostuuid( uuid, &timeout ))
- {
- 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};
- WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) );
- if (!ret) return NULL;
- 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] );
- 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))
+ 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;
+ 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 );
+
+ 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)
{
- unsigned int i, j;
- WCHAR *ret, *p;
-
- close( file );
- if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL;
- for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] );
- p[8] = '-';
- for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] );
- p[13] = '-';
- for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] );
- p[18] = '-';
- for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
- p[23] = '-';
- for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] );
- ret[i] = 0;
- return ret;
+ 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
- return heap_strdupW( compsysproduct_uuidW );
+ if (!uuid || !memcmp( uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
+
+ 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 )
--
2.20.1