SystemStats has no means of getting HD serial number

There is currently no means of getting the primary HD serial number or CPU serial number in the juce::SystemStats classes.

It is possible on both mac OS and Windows to retrieve these numbers.

This feature would be very useful for uniquely identifying a user’s computer.

I’m currently using my own versions of the code presented in those links. However, I trust the JUCE code for this kind of thing much more than I trust my own code, and having an official JUCE way to retrieve these values would be a welcome addition to the framework.

Is there a reason this functionality was omitted?

I’m not sure iOS and Android supports those features? Would be curious to see if permissions get in the way.

FWIW, I’ve been using juce::File::hashCode64 for the purpose of uniquely identifying machines by looking up each fixed hard disk. Here’s an example from my modules: sp::createSystemHash. This is all used in production code in various projects. Do note that the drives weren’t the only source for creating a unique hash.

You don’t get issues with installations where multiple different users on a single machine are using your software? Or do you store your license file within the user and not a system shared folder?

Thanks for the link!

unfortunately, findFileSystemRoots on mac just does this:

void File::findFileSystemRoots (Array<File>& destArray)
{
    destArray.add (File ("/"));
}

I don’t know too much about hashing, but I believe if you provide it the same input, it will always produce the same output. I could be wrong, though.

Here’s what I currently do to get the primary HD serial number:

juce::String SystemQuery::get_platform_serial()
{
	juce::String result;

	io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
	CFStringRef platformSerial = (CFStringRef)IORegistryEntryCreateCFProperty(ioRegistryRoot,
		CFSTR(kIOPlatformSerialNumberKey),
		kCFAllocatorDefault,
		0);
	IOObjectRelease(ioRegistryRoot);

	result = juce::String(CFStringGetCStringPtr(platformSerial, kCFStringEncodingMacRoman));
	//NSString* result = (NSString*)CFBridgingRelease( CFStringGetCStringPtr( platformSerial, kCFStringEncodingMacRoman) );
	CFRelease(platformSerial);

	return result;
}

This code produces the same serial number shown in the System Profiler window

The information is stored in the user folder.

1 Like

I don’t know too much about hashing, but I believe if you provide it the same input, it will always produce the same output. I could be wrong, though.

That also applies to fixed drive serials when multiple users use the same machine.

If you look at my function, it doesn’t only use drive information but also user specific information so as to account for that event.

Hey @jrlanglois

I’m considering attempting to split my machine ID implementation to use the device identifiers (stable) on Mac – and then root folder stuff on win (which I need to check)

One other thing I noticed is SystemStats::getComputerName() ← back when I was using this a few years ago – I noticed it was changing depending on the network the user was connected to.

Not sure if you’re having a problem with that – but fairly confident that was the case

Hm I’m guessing that was on Windows? Thanks for the heads up.

To be totally transparent - I think the approach of using any of these details for the purpose of identifying a machine is probably the wrong way to go. It’s good for framing some user control logic, but the factors stack up against this method because of the lack of consistency for the information from the APIs - that and the data from those APIs can be possible security holes and/or they’re frowned upon because it requires user permissions and may be construed as tracking.

My thinking is that it’s probably safer and less hassle for a user if a developer were to cache a UUID somewhere. If that UUID goes away or changes in some fashion, the user would be required to login again.

1 Like

Yeah – I tried the root folder hash thing and I think it would suffer a collision of being the same on multiple machines as well.

The UUID thing is a good approach – but it’s pretty loose security wise, if anyone was to catch on, moving the license along with that UUID would be equivalent to cracking the software – however I suppose using that in conjunction with some computer name symbols in a hash would be able as stable & secure as any other approach.

I just wish there was a reliable cross platform machine ID in the framework and it’d be all solved!

1 Like