4

Windows では、ライセンスを PC に結び付けるために使用される PC 固有の一意のキーを生成します。これは wxWidgets を使用した C++ アプリであり、理論的にはクロスプラットフォーム互換ですが、Mac 側では維持されていません。キーを生成するために Win32 固有のコードを使用しています... Mac で同様のことを行うにはどうすればよいでしょうか?

4

3 に答える 3

4

whitelionV と blahdiblah の回答を詳しく調べたところ、次の便利なページが見つかりました。

プログラムによるシステムのシリアル番号へのアクセス

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

// Returns the serial number as a CFString. 
// It is the caller's responsibility to release the returned CFString when done with it.
void CopySerialNumber(CFStringRef *serialNumber)
{
    if (serialNumber != NULL) {
        *serialNumber = NULL;

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

        if (platformExpert) {
            CFTypeRef serialNumberAsCFString = 
                IORegistryEntryCreateCFProperty(platformExpert,
                                                CFSTR(kIOPlatformSerialNumberKey),
                                                kCFAllocatorDefault, 0);
            if (serialNumberAsCFString) {
                *serialNumber = serialNumberAsCFString;
            }

            IOObjectRelease(platformExpert);
        }
    }
}

プログラムによる組み込み MAC アドレスへのアクセス

#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>

static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize);

static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
{
    kern_return_t           kernResult; 
    CFMutableDictionaryRef  matchingDict;
    CFMutableDictionaryRef  propertyMatchDict;

    matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);

    if (NULL == matchingDict) {
        printf("IOServiceMatching returned a NULL dictionary.\n");
    }
    else {
        propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                                      &kCFTypeDictionaryKeyCallBacks,
                                                      &kCFTypeDictionaryValueCallBacks);

        if (NULL == propertyMatchDict) {
            printf("CFDictionaryCreateMutable returned a NULL dictionary.\n");
        }
        else {
            CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
            CFRelease(propertyMatchDict);
        }
    }

    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, matchingServices);    
    if (KERN_SUCCESS != kernResult) {
        printf("IOServiceGetMatchingServices returned 0x%08x\n", kernResult);
    }

    return kernResult;
}

static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize)
{
    io_object_t     intfService;
    io_object_t     controllerService;
    kern_return_t   kernResult = KERN_FAILURE;

    if (bufferSize < kIOEthernetAddressSize) {
        return kernResult;
    }

    bzero(MACAddress, bufferSize);

    while ((intfService = IOIteratorNext(intfIterator)))
    {
        CFTypeRef   MACAddressAsCFData;        
        kernResult = IORegistryEntryGetParentEntry(intfService,
                                                   kIOServicePlane,
                                                   &controllerService);

        if (KERN_SUCCESS != kernResult) {
            printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kernResult);
        }
        else {
            MACAddressAsCFData = IORegistryEntryCreateCFProperty(controllerService,
                                                                 CFSTR(kIOMACAddress),
                                                                 kCFAllocatorDefault,
                                                                 0);
            if (MACAddressAsCFData) {
                CFShow(MACAddressAsCFData); // for display purposes only; output goes to stderr

                CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);
                CFRelease(MACAddressAsCFData);
            }

            (void) IOObjectRelease(controllerService);
        }

        (void) IOObjectRelease(intfService);
    }

    return kernResult;
}

int main(int argc, char *argv[])
{
    kern_return_t   kernResult = KERN_SUCCESS;
    io_iterator_t   intfIterator;
    UInt8           MACAddress[kIOEthernetAddressSize];

    kernResult = FindEthernetInterfaces(&intfIterator);

    if (KERN_SUCCESS != kernResult) {
        printf("FindEthernetInterfaces returned 0x%08x\n", kernResult);
    }
    else {
        kernResult = GetMACAddress(intfIterator, MACAddress, sizeof(MACAddress));

        if (KERN_SUCCESS != kernResult) {
            printf("GetMACAddress returned 0x%08x\n", kernResult);
        }
        else {
            printf("This system's built-in MAC address is %02x:%02x:%02x:%02x:%02x:%02x.\n",
                    MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3], MACAddress[4], MACAddress[5]);
        }
    }

    (void) IOObjectRelease(intfIterator);   // Release the iterator.

    return kernResult;
}

MAC は、より予測可能であるため、おそらく好ましいと思われますが、次のように警告しています。

ネットブートは、複数のビルトイン イーサネット ポートを備えたシステムに問題をもたらします。これらのシステムのプライマリ Ethernet ポートは、NetBoot サーバーに接続されているポートです。これは、プライマリ ポートを検索すると、ネットブートに使用されたポートに応じて、組み込みの MAC アドレスのいずれかが返される可能性があることを意味します。「組み込み」には、拡張カードに常駐するイーサネット ポートは含まれないことに注意してください。

これは、常に同じ値が返されるとは限らないということでしょうか?

于 2012-02-04T15:04:36.117 に答える
2

system_profiler電話して「シリアル番号」を探すだけです

/usr/sbin/system_profiler | grep "Serial Number (system)"

同じ情報を取得するためのプログラム的な方法があるかもしれませんが、私はそれを直接知りません。

于 2012-02-03T00:47:13.183 に答える
1

マシンを一意に識別するために、MACアドレスの使用を試みることができます。プロセスは簡単ではありませんが、非常に簡単です。クロスプラットフォームのオープンソースライブラリはたくさんあります。

実際、このAppledevの例を試すことができます

于 2012-02-03T00:42:15.087 に答える