DanielH
DanielH

Reputation: 133

Get OSX HD Serial Number

I need to get the HD serial Number on OSX. I could not find any Delphi examples so far.

I found this C++ Builder example:

AnsiString GetSerialNumber()
{
    AnsiString result;

    io_service_t platformExpert =
        IOServiceGetMatchingService(kIOMasterPortDefault,
            IOServiceMatching("IOPlatformExpertDevice"));

    if (platformExpert) {
        CFTypeRef serialNumberAsCFString =
            IORegistryEntryCreateCFProperty(platformExpert,
                                            CFSTR(kIOPlatformSerialNumberKey),
                                            kCFAllocatorDefault, 0);
        if (serialNumberAsCFString)
        {
            result = CFStringGetCStringPtr((CFStringRef) serialNumberAsCFString, 0);
            CFRelease(serialNumberAsCFString);
        }

        IOObjectRelease(platformExpert);
    }

    return result;
}

I'm using XE7.

Help porting this to Delphi will be highly appreciated.

@David - in Macapi.IOKit, IOServiceGetMatchingService point to CFDictionaryRef while IOServiceMatching point to CFMutableDictionaryRef.

I could not find any doc how to cast CFMutableDictionaryRef to CFDictionaryRef.

That's what I came up with so far:

function GetMacSerialNo: String;
  Const
  kIOPlatformSerialNumberKey = 'IOPlatformSerialNumber';
  Var
  PlatformExpert: io_service_t;
  M: CFMutableDictionaryRef;
  SerialNumberAsCFString: CFTypeRef;
  _AnsiChar: PAnsiChar;
begin

  M := IOServiceMatching('IOPlatformExpertDevice');

  PlatformExpert := IOServiceGetMatchingService(kIOMasterPortDefault,M); --> E2010 Incompatible types: 'CFDictionaryRef' and 'CFMutableDictionaryRef'

  SerialNumberAsCFString := IORegistryEntryCreateCFProperty(PlatformExpert,
                            CFSTR(kIOPlatformSerialNumberKey),kCFAllocatorDefault,0);

  _AnsiChar := CFStringGetCStringPtr(SerialNumberAsCFString,0);

  Result := String(AnsiString(_AnsiChar));

end;

Upvotes: 0

Views: 970

Answers (1)

DanielH
DanielH

Reputation: 133

Turns out casting a CFMutableDictionaryRef is simpler than I thought. Here's the working code for anyone who may needs it.

Function GetMacSerialNo: String;
  Const
  kIOPlatformSerialNumberKey = 'IOPlatformSerialNumber';
  Var
  PlatformExpert: io_service_t;
  M: CFMutableDictionaryRef;
  SerialNumberAsCFString: CFTypeRef;
  _AnsiChar: PAnsiChar;
begin

  M := IOServiceMatching('IOPlatformExpertDevice');
  PlatformExpert := IOServiceGetMatchingService(kIOMasterPortDefault,CFDictionaryRef(M));

  SerialNumberAsCFString := IORegistryEntryCreateCFProperty(PlatformExpert,
                            CFSTR(kIOPlatformSerialNumberKey),kCFAllocatorDefault,0);

  _AnsiChar := CFStringGetCStringPtr(SerialNumberAsCFString,0);

  Result := String(AnsiString(_AnsiChar));

  IOObjectRelease(PlatformExpert);

End;

Upvotes: 1

Related Questions