Использование IOKit для возврата Mac Серийный номер возвращает 4 дополнительных символа
Я играю с IOKit и имею следующий код. Основная идея - передать ключ платформыExpert в это приложение командной строки небольшого ядра и распечатать декодированную строку. Тестовый пример - "серийный номер". Код ниже при запуске, как:
./скомпилированный серийный номер
Почти работает, но возвращает последние 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;
}
Ответы
Ответ 1
Возможно, вы неправильно интерпретируете значение параметра серийного номера. Если я использую 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 .........
(Я имею X'd мой серийный номер Mac, за исключением повторной части.)
Вы не видите нулевые символы, когда вы показываете строку, потому что они нулевые. Я не знаю, почему у него есть то, что похоже на несколько полей, разделенных нулевыми символами, но это то, что кажется.
Я рекомендую провести дальнейшее расследование, чтобы убедиться, что нет спецификации того, как эти данные должны интерпретироваться; если вы ничего не найдете, я пропустил бы первый запуск нулей и получил бы все после этого до следующего запуска нулей.
Ответ 2
Более упрощенное решение:
#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