Inconsistent MACAddress::findAllAddresses for UDID


I’m using MACAddress::findAllAddresses() as a way to generate a UDID (unique device ID) on Windows, by concatenating the returned addresses. On mac and linux, where I can rely on gethostuuid(), but since on Windows I decided to use the mac addresses, since it’s a very common way to get a UDID.

But it seems that the addresses list returned by MACAddress::findAllAddresses() can change, and every day I have some client complaining that the auth key is not working. A system crash, or some unrelated software install are sufficient to get me different results. I’m not sure if only the order or the actual contents of the addresses list is changed, because I only have access to the final ID I generate. But I can see the same addresses repeated in different places of the final generated id.

For example, those are all ids of the same computer, without any hardware change, just software. the mac address blocks seems to be in different order:


So, is there a way I rely on the mac address list order?

Or even better… is there a better way to get solid UDID on windows?

Can you just sort the list before using it?

Yes, I can sort it, but I need to understand if the contents can change without any hardware changes. If some physical or virtual mac address is added or changed after a Windows update, crashing, installing Word or something, my UDID will still be broken.

I’d recommend using HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid or
File::getFileIdentifier on the c:\windows folder or something similar.

Network cards aren’t constant, they can be USB, bluetooth, virtual, VPN adapters, disabled, etc.

MachineGuid may not be that unique.

I see some people suggest to use System.Identity.UniqueID. Can JUCE fetch that?

Before replacing all my junk cross platform code to JUCE, I used to do the following. Can JUCE do those queries?

		std::string pid;
		std::string bid;
		// query from unmanaged code
		// Get Processor ID
		ManagementObjectSearcher ^ mbs = gcnew ManagementObjectSearcher("Select ProcessorID From Win32_processor");
		ManagementObjectCollection ^ mbsList = mbs->Get();
		for each ( ManagementObject ^ mo in mbsList )
			pid = WINSTR_TO_STDSTR( mo["ProcessorID"]->ToString() );
		// Get Board ID
		ManagementObjectSearcher ^ mbs = gcnew ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard");
		ManagementObjectCollection ^ mbsList = mbs->Get();
		for each (ManagementObject ^ mo in mbsList)
			bid = WINSTR_TO_STDSTR( mo["SerialNumber"]->ToString() );