// TO COMPILE: cl machineid.cc /EHsc advapi32.lib
#include
#include
using namespace std;
#include
#include
#include
void main() {
// 从机器CPU和网卡产生机器唯一ID
unsigned __int32 machine_id[4];
// 获取CPU vender ID和序列码, 参考 http://www.sandpile.org/ia32/cpuid.htm.
unsigned __int8 vendor_id[12] = "unknown";
unsigned __int32 serial_number[4] = {0, 0, 0, 0};
try {
__asm {
mov eax, 0
cpuid
mov dword ptr vendor_id[0], ebx
mov dword ptr vendor_id[4], edx
mov dword ptr vendor_id[8], ecx
mov eax, 3
cpuid
mov dword ptr serial_number[0], eax
mov dword ptr serial_number[1], edx
mov dword ptr serial_number[2], ebx
mov dword ptr serial_number[3], ecx
}
} catch (...) {
// 不是所有CPU都支持CPUID指令
}
machine_id[0] = serial_number[0] ^ *(reinterpret_cast(vendor_id));
machine_id[1] = serial_number[1] ^ *(reinterpret_cast(vendor_id + 3));
machine_id[2] = serial_number[2] ^ *(reinterpret_cast(vendor_id + 6));
machine_id[3] = serial_number[3] ^ *(reinterpret_cast(vendor_id + 8));
// 获取网卡物理地址,参考http://msdn.microsoft.com/en-us/library/ms797780.aspx
HKEY key;
if (!SUCCEEDED(::RegOpenKeyA(HKEY_LOCAL_MACHINE, "software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards", &key))) {
cout << "Cannot open software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; return; } int adapter_index = 0; do { size_t buffer_size = 40; LONG result = ERROR_SUCCESS; char* key_name = new char[buffer_size]; do { result = ::RegEnumKeyA(key, adapter_index++, key_name, buffer_size); if (result == ERROR_MORE_DATA) { delete[] key_name; key_name = new char[buffer_size *= 2]; } else { break; } } while (true); if (!SUCCEEDED(result) || result == ERROR_NO_MORE_ITEMS) { delete[] key_name; break; } HKEY sub_key; if (!SUCCEEDED(::RegOpenKeyA(key, key_name, &sub_key))) { cout << "Cannot open " << buffer_size =" 40;" adapter_name =" new" file_handle =" ::CreateFileA(device_name," query =" OID_802_3_PERMANENT_ADDRESS;" mac_size =" sizeof(mac_address);">(mac_address));
machine_id[(adapter_index + 1) % 4] ^= *(reinterpret_cast(mac_address + 1));
machine_id[(adapter_index + 2) % 4] ^= *(reinterpret_cast(mac_address + 2));
machine_id[(adapter_index + 3) % 4] ^= *(reinterpret_cast(mac_address + 1));
}
}
delete[] key_name;
} while (true);
::RegCloseKey(key);
cout <<>
Tuesday, May 26, 2009
如何生成机器唯一ID
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment