Module: wine Branch: master Commit: 96c46b1ca7a0718c8b1796770593c4ad9cb3e850 URL: http://source.winehq.org/git/wine.git/?a=commit;h=96c46b1ca7a0718c8b17967705...
Author: Hans Leidekker hans@codeweavers.com Date: Mon Oct 24 10:04:21 2016 +0200
wbemprox: Return the hardware UUID for Win32_ComputerSystemProduct.UUID on macOS.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wbemprox/builtin.c | 51 +++++++++++++++++++++++++++++++++++++++------ dlls/wbemprox/tests/query.c | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index c8c2f4c..ee47cc7 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -22,6 +22,9 @@
#include "config.h" #include <stdarg.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -414,7 +417,7 @@ static const struct column col_compsys[] = static const struct column col_compsysproduct[] = { { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY }, - { prop_uuidW, CIM_STRING } + { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC } }; static const struct column col_datafile[] = { @@ -1055,10 +1058,6 @@ static const struct record_bios data_bios[] = { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, bios_smbiosbiosversionW, bios_versionW } }; -static const struct record_computersystemproduct data_compsysproduct[] = -{ - { compsysproduct_identifyingnumberW, compsysproduct_uuidW } -}; static const struct record_param data_param[] = { { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, @@ -1321,6 +1320,46 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co return status; }
+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 + return heap_strdupW( compsysproduct_uuidW ); +} + +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; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_computersystemproduct *)table->data; + rec->identifyingnumber = compsysproduct_identifyingnumberW; + rec->uuid = get_compsysproduct_uuid(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + struct dirstack { WCHAR **dirs; @@ -3077,7 +3116,7 @@ static struct table builtin_classes[] = { class_biosW, SIZEOF(col_bios), col_bios, SIZEOF(data_bios), 0, (BYTE *)data_bios }, { class_cdromdriveW, SIZEOF(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive }, { class_compsysW, SIZEOF(col_compsys), col_compsys, 0, 0, NULL, fill_compsys }, - { class_compsysproductW, SIZEOF(col_compsysproduct), col_compsysproduct, SIZEOF(data_compsysproduct), 0, (BYTE *)data_compsysproduct }, + { class_compsysproductW, SIZEOF(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct }, { class_datafileW, SIZEOF(col_datafile), col_datafile, 0, 0, NULL, fill_datafile }, { class_desktopmonitorW, SIZEOF(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor }, { class_directoryW, SIZEOF(col_directory), col_directory, 0, 0, NULL, fill_directory }, diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index d41aa11..2513807 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -1176,6 +1176,45 @@ static void test_OperatingSystem( IWbemServices *services ) SysFreeString( wql ); }
+static void test_ComputerSystemProduct( IWbemServices *services ) +{ + static const WCHAR uuidW[] = {'U','U','I','D',0}; + static const WCHAR queryW[] = + {'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','P','r','o','d','u','c','t',0}; + BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW ); + IEnumWbemClassObject *result; + IWbemClassObject *service; + VARIANT value; + CIMTYPE type; + HRESULT hr; + DWORD count; + + hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result ); + if (hr != S_OK) + { + win_skip( "Win32_ComputerSystemProduct not available\n" ); + return; + } + + hr = IEnumWbemClassObject_Next( result, 10000, 1, &service, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + + type = 0xdeadbeef; + VariantInit( &value ); + hr = IWbemClassObject_Get( service, uuidW, 0, &value, &type, NULL ); + 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( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "uuid %s\n", wine_dbgstr_w(V_BSTR(&value)) ); + VariantClear( &value ); + + IWbemClassObject_Release( service ); + IEnumWbemClassObject_Release( result ); + SysFreeString( query ); + SysFreeString( wql ); +} + START_TEST(query) { static const WCHAR cimv2W[] = {'R','O','O','T','\','C','I','M','V','2',0}; @@ -1214,6 +1253,7 @@ START_TEST(query) test_GetNames( services ); test_SystemSecurity( services ); test_OperatingSystem( services ); + test_ComputerSystemProduct( services );
SysFreeString( path ); IWbemServices_Release( services );