使用IOKit返回Mac的序列号会返回4个额外字符

时间:2012-01-06 03:53:14

标签: objective-c core-foundation iokit

我正在使用IOKit并拥有以下代码,一般的想法是将platformExpert密钥传递给这个小型核心基础命令行应用程序并让它打印解码后的字符串。测试用例是“序列号”。运行时的代码如下:

./编译序列号

几乎可以工作,但在字符串的开头返回序列号的最后4个字符,即对于C12D2JMPDDQX这样的示例序列,它将返回

DDQXC12D2JMPDDQX

有什么想法吗?

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main (int argc, const char * argv[]) {
    CFStringRef parameter = CFSTR("serial-number");
    if (argv[1]) {
       parameter = CFStringCreateWithCString(
                                 NULL,
                                 argv[1],
                                 kCFStringEncodingUTF8);
    }

    CFDataRef data;

    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert)
    {
        data = IORegistryEntryCreateCFProperty(platformExpert,
                                               parameter,
                                               kCFAllocatorDefault, 0);
    }

    IOObjectRelease(platformExpert);
    CFIndex bufferLength = CFDataGetLength(data);  
    UInt8 *buffer = malloc(bufferLength);
    CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
    CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault,
                                                 buffer,
                                                 bufferLength,
                                                 kCFStringEncodingUTF8,
                                                 TRUE);
    CFShow(string);
    return 0;
}

2 个答案:

答案 0 :(得分:6)

更简化的解决方案:

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main()
{
    CFMutableDictionaryRef matching = IOServiceMatching("IOPlatformExpertDevice");
    io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
    CFStringRef serialNumber = IORegistryEntryCreateCFProperty(service,
        CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
    const char* str = CFStringGetCStringPtr(serialNumber,kCFStringEncodingMacRoman);
    printf("%s\n", str); //->stdout
    //CFShow(serialNumber); //->stderr
    IOObjectRelease(service);
    return 0;
}

编译:

  

clang -framework IOKit -framework ApplicationServices cpuid.c -o cpuid

如果你愿意,可以从github分叉;)

https://github.com/0infinity/IOPlatformSerialNumber

答案 1 :(得分:3)

您可能误解了序列号参数的值。如果我使用ioreg -f -k serial-number,我会得到:

    |   "serial-number" = 
    |     00000000: 55 51 32 00 00 00 00 00 00 00 00 00 00 XX XX XX XX UQ2..........XXXX
    |     00000011: XX XX XX XX 55 51 32 00 00 00 00 00 00 00 00 00 00 XXXXUQ2..........
    |     00000022: 00 00 00 00 00 00 00 00 00                         .........

(除了重复的部分,我已经把我的Mac的序列号X了。)

显示字符串时,您看不到空字符,因为它们是空字符。我不知道为什么它看起来像是由空字符分隔的多个字段,但这就是它的样子。

我建议进一步调查,以确保没有关于如何解释这些数据的规范;如果你没有找到任何东西,我会跳过第一次空值并在之后获取所有内容,直到下一次空值运行。