views:

698

answers:

5

Is there any easy way to get the serial number of all the hard disks in a Mac using any API's?

Basically looking for a unique identifier for hard disk, with which I should make out that the Hard disk has been used(referred) by my application or not. Please let me know if there is any other solution.

Note: I need this solution in 10.4 and above.

+3  A: 

I'm not sure if "AppleUSBEHCI" is the proper thing to look for but you can retrieve this sort of data using the IOKit framework:

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

kern_return_t   kr;
io_iterator_t   io_objects;
io_service_t    io_service;

kr = IOServiceGetMatchingServices(kIOMasterPortDefault,
            IOServiceNameMatching("AppleUSBEHCI"), &io_objects);

if(kr != KERN_SUCCESS)
    exit(1);

while((io_service= IOIteratorNext(io_objects)))
{
    kr = IORegistryEntryCreateCFProperties(io_service, &service_properties, kCFAllocatorDefault, kNilOptions);
    if(kr == KERN_SUCCESS)
    {
        NSDictionary * m = (NSDictionary *)service_properties;
        NSLog(@"%@", m);
        CFRelease(service_properties);
    }

    io_iterator_t   iter;
    //handle kr error
    kr = IORegistryEntryGetChildIterator(io_service, kIOServicePlane, &iter);

    io_registry_entry_t     child;
    while( (child = IOIteratorNext( iter )))
    {
        kr = IORegistryEntryCreateCFProperties(child, &child_props,  kCFAllocatorDefault, kNilOptions );
        NSLog(@"Child props: %@", child_props);
        //release child_props
    }

    IOObjectRelease(io_service);
}

IOObjectRelease(io_objects);
diciu
AppleAHCIDiskDriver - not resulting hard disk which are connected are USB.By looking in system profiler USB HD was using"Host Controller Driver: AppleUSBEHCI"so I tried using AppleUSBEHCI instead AppleAHCIDiskDriver but did not resulted any result.not sure I am missing some thing.
Girish Kolari
diciu
I appreciate your help. I tied mouviciel solution but did not work.when I tried using IORegistryEntryGetChildIterator - it return error(268435459), I just called this after IOServiceGetMatchingServices, not sure what am I missing.
Girish Kolari
You probably called IORegistryEntryGetChildIterator on the iterator which doesn't make sense.I've edited my answer to illustrate iterating through children of a ioregistryentry. Note that I've tested with a USB stick - a HDD may or may not appear in the same way. You need to do some reading on IOKit before writing production code.
diciu
it worked, you are right I was called IORegistryEntryGetChildIterator on the iterato.I will consider your suggestion to read IOKit before going to production.thanks for your help.
Girish Kolari
is there any way to get 'BSD Name:' in this process. I could see BSD Name in System profiler but I could not see this in the 'child_props' can I get some help on this.Basically I am trying to map serial number with drive (BSD name - since it is unique).
Girish Kolari
A: 

maybe you can just place a hidden file on a hard disk that your app has used? That's e.g. how apple's Time Machine does it.

V1ru8
good suggestion, I can consider this solution only if get some information from Hard disk. If file is get deleted, I can not recognize it any more in my app.
Girish Kolari
A: 

Have a look at IOKit.

There are two handy tools on your Mac to find out about the possibilities of it:

  • ioreg, a command line tool
  • IORegistryExplorer, the same with a GUI.
Georg
A: 

FSGetVolumeInfo() together with kFSVolInfoDriveInfo option should give you drive information.

mouviciel
When I use this I am getting drive number and drive reference number as '0'.
Girish Kolari
+1  A: 

I think it's better to get the Volume UUID (which appears in the Disk Utility, for example.) UUID can be obtained using the Disk Arbitration framework, which is slightly higher-level than IOKit and easier to use. Create DADiskRef using DADiskCreateFromBSDName, and use DADiskCopyDescription to get the info dictionary, and look up the key kDADiskDescriptionMediaUUIDKey. Info on the mount point etc. can be obtained by statfs.

That said, it might be easier just to invoke the command-line utility diskutil with the option -plist to get the info in the plist format.

The sample code FSMegaInfo might also be instructive how to get much more info about a disk.

Yuji
thanks for valuable information.As per my understanding UUID is generated in system not sure it can be considered as unique. In my system I am not able to see UUID for the device.
Girish Kolari
UUID is an acronym for Universally Unique ID, and it's unique. It's used for example to control what to mount in `/etc/fstab`.It's also weird that you don't see the UUID. What does `diskutil info /dev/disk0s2` return on your machine? Don't you see the entry `Volume UUID` in the list? You might need to change `/disk0s2` above to what you actually have. Check first with `diskutil list`.
Yuji