File::getVolumeSerialNumber always returns 0


#1

On the mac File::getVolumeSerialNumber always returns 0 because the function that does the hard work, actually doesn’t do any hard work :wink:

juce_Mac_Files.cpp

const String juce_getVolumeLabel (const String& filenameOnVolume, int& volumeSerialNumber) throw()
{
    volumeSerialNumber = 0;
    return String::empty;
}

I guess it should be possible to retrieve the serial number of the drive because I can see it in the system profiler.


#2

Ah, I didn’t realise that was still unfinished. Yes, I’m sure it’s possible… No idea how to do it though!


#3

File::getVolumeSerialNumber() always returns 0 in the current juce_posix_SharedCode.h.
I should not use this function?


#4

Yes, probably best to avoid it. It’s there because many many years ago I implemented in on windows, but it doesn’t really translate well across other platforms. I should probably remove it, TBH, (or maybe convert it to a win32-specific utility function)


#5

thanks, ok-


#6

At almost a decade later, it’s time that this was solved somewhat. This function will grab the serial numbers of ALL HDs attached to an OS X system. It does this by getting the IO Registry dictionary in charge of ports, and scans it for any entries containing “AppleAHCIDiskDriver”. When it finds one, it grabs the “serial Number” entry in that dictionary field and tosses it into a StringArray. The StringArray with all HD serials is returned.

StringArray SystemQuery::get_internal_hd_serials() {
		String result;
		StringArray results;
		io_iterator_t iterator = IO_OBJECT_NULL;
		io_object_t object = IO_OBJECT_NULL;
		CFMutableDictionaryRef properties = NULL;
		kern_return_t kernResult = IORegistryCreateIterator(kIOMasterPortDefault, kIOServicePlane, kIORegistryIterateRecursively, &iterator );
		if( kernResult != KERN_SUCCESS ) {
			result = "get_internal_hd_serials couldn't get iterator!";
			results.add( result );
		} else {
			while( (object = IOIteratorNext( iterator )) != IO_OBJECT_NULL ) {
				//properties = NULL;
				kernResult = IORegistryEntryCreateCFProperties(object, &properties, kCFAllocatorDefault, 0);
				if( kernResult != KERN_SUCCESS || properties == NULL ){
					result = "get_internal_hd_serials couldn't get properties dictionary!";
					results.add( result );
					break;
				} else {
					//got our dictionary.   go thru the properties and see if you can find what you need.

					if( CFDictionaryContainsValue( properties, CFSTR("AppleAHCIDiskDriver"))) {
						CFStringRef val = (CFStringRef)CFDictionaryGetValue( properties, CFSTR("Serial Number") ) ;
						result = String::fromCFString( val );
						results.add(result);
						
						std::cout << "get_internal_hd_serials() found: " << result << "\n";
					}

				}
				CFRelease( properties );
				properties = NULL;

				IOObjectRelease( object );
				object = IO_OBJECT_NULL;
			}
		}
		if( properties != NULL ) {
			CFRelease( properties );
		}
		if( iterator != IO_OBJECT_NULL ) {
			IOObjectRelease( iterator );
		}
		if( object != IO_OBJECT_NULL ) {
			IOObjectRelease( object );
		} 
     return results;
}

#7