diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp index 7aabeed945..dc1205c6ee 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp +++ b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp @@ -18,6 +18,11 @@ #include #include #include +#include +#include +#include +#include +#include #define REAL_TIME_CRITICAL_SECTION 0 @@ -125,6 +130,84 @@ ArchHooks_darwin::~ArchHooks_darwin() delete TimeCritMutex; } +RString ArchHooks_darwin::GetMachineId() +{ + RString ret; + CFMutableDictionaryRef dict = IOServiceMatching( "IOPlatformExpertDevice" ); + CFMutableDictionaryRef property; + io_service_t service; + + if( dict ) + { + // This consumes the reference. + service = IOServiceGetMatchingService( kIOMasterPortDefault, dict ); + + if( service ) + { + CFTypeRef serial; + CFStringRef key = CFSTR( "IOPlatformSerialNumber" ); // kIOPlatformSerialNumberKey + + serial = IORegistryEntryCreateCFProperty( service, key, kCFAllocatorDefault, 0 ); + + if( serial ) + { + ret = CFStringGetCStringPtr( (CFStringRef)serial, kCFStringEncodingMacRoman ); + CFRelease( serial ); + } + IOObjectRelease( service ); + } + } + + dict = IOServiceMatching( kIOEthernetInterfaceClass ); + + if( !dict ) + return ret; + + property = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks ); + + if( !property ) + { + CFRelease( dict ); + return ret; + } + + CFDictionarySetValue( property, CFSTR(kIOPrimaryInterface), kCFBooleanTrue ); + CFDictionarySetValue( dict, CFSTR(kIOPropertyMatchKey), property ); + CFRelease( property ); + + io_iterator_t iter; + + if( IOServiceGetMatchingServices(kIOMasterPortDefault, dict, &iter) != KERN_SUCCESS ) + return ret; + while( (service = IOIteratorNext(iter)) ) + { + CFTypeRef data; + io_object_t controller; + + if( IORegistryEntryGetParentEntry(service, kIOServicePlane, &controller) != KERN_SUCCESS ) + { + IOObjectRelease( service ); + continue; + } + + data = IORegistryEntryCreateCFProperty( controller, CFSTR(kIOMACAddress), + kCFAllocatorDefault, 0 ); + if( data ) + { + const uint8_t *p = CFDataGetBytePtr( (CFDataRef)data ); + + ret += ssprintf( "-%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5] ); + CFRelease( data ); + } + IOObjectRelease( controller ); + IOObjectRelease( service ); + } + IOObjectRelease( iter ); + return ret; +} + void ArchHooks_darwin::DumpDebugInfo() { RString systemVersion; diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h index 996a530a18..332f33f61c 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h +++ b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h @@ -10,6 +10,7 @@ public: ArchHooks_darwin(); ~ArchHooks_darwin(); RString GetArchName() { return "OS X"; } + RString GetMachineId(); void DumpDebugInfo(); RString GetPreferredLanguage(); void EnterTimeCriticalSection();