1

私はIOKitで遊んでいて、次のコードを持っています。一般的な考え方は、platformExpertキーをこの小さなコアFoundationコマンドラインアプリケーションに渡して、デコードされた文字列を出力させることです。テストケースは「シリアル番号」です。次のように実行した場合の以下のコード:

./コンパイルされたシリアル番号

ほとんど機能しますが、文字列の先頭にあるシリアル番号の最後の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;
}
4

2 に答える 2

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

于 2012-05-28T22:41:40.993 に答える
3

serial-number パラメータの値を誤解している可能性があります。を使用する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 アウトしました。)

文字列を表示しても、null 文字は表示されません。これは、null 文字であるためです。ヌル文字で区切られた複数のフィールドのように見える理由はわかりませんが、それがそのようです。

このデータの解釈方法に関する仕様がないことを確認するために、さらに調査を行うことをお勧めします。何も見つからない場合は、null の最初の実行をスキップして、その後の null の次の実行まですべてを取得します。

于 2012-01-06T05:47:45.517 に答える