• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: FSGetVolumeMountInfoSize returns error -36?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FSGetVolumeMountInfoSize returns error -36?


  • Subject: Re: FSGetVolumeMountInfoSize returns error -36?
  • From: James Bucanek <email@hidden>
  • Date: Thu, 19 Aug 2010 09:10:35 -0700

Chris Suter <mailto:email@hidden> wrote (Thursday, August 19, 2010 6:36 PM +1000):

On Thu, Aug 19, 2010 at 8:33 AM, James Bucanek <email@hidden>wrote:

James Bucanek <mailto:email@hidden> wrote (Tuesday, August 17,
2010 11:04 AM -0700):

For anyone stumbling across this thread in the future, it's actually even
simpler than I imagined. All you have to do is ...
<clip>

That seems a whole lot more complicated than just calling statfs and looking at f_mntfromname. For example:

Chris,

I agree that your solution is simpler, and (in retrospect) I'm sure it would work just fine. I considered something like that when I began, but that solution makes an awful lot of assumptions--assumptions about how the OS names devices, assumptions about how those names relate to hierarchal organization of those devices, and so on. That was more assumptions that I was conformable making.

Ultimately, it turns out that you probably can safely make these assumptions, much the way code with hard-coded paths to /tmp (written thirty years ago) still compile and runs today.

I would hope that the solution that I settled on is more robust, future-proof, and "correct" even if it's not more effective. I'm not a stickler about these things--I freely admit to using property lists to update the contents of loginwindow.plist (3 lines of Objective-C code), instead of the "correct" and official solution which is to use AppleScript (what seems like 5 pages of dense, nearly indecipherable, Carbon gibberish).

Since we're sharing, here's my final solution. This is a method in my CarbonVolume class, an Objective-C wrapper around all things FSVolumeRefNum:

- (id)wholeDeviceIdentifier
{
// Returns an immutable object, suitable for use as a dictionary key, that acts as a unique identifier for the
// logical device that contains the receiver's volume.
// For a hard disk, CD, or RAID this will be the device name of the (logical) drive that contains the partition
// that contains the receiver's volume. For volumes not associated with a "whole" media object, it returns the
// volume's filesystem identifier (as an NSNumber).
// Use the return value to compare with the wholeDeviceIdentifier for other volumes to determine if the two volumes
// are known to share a common, physical, device.


// Begin by obtaining the default value, which is the filesystem identifier for the volume.
// If *anything* goes wrong trying to locate the whole IOMedia object in the I/O Registry,
// return this value instead.
id identifier = [[self fileManagerAttributes] objectForKey:NSFileSystemNumber];


const char* deviceName = [self deviceName];
if (deviceName[0]=='\0' || deviceName[0]=='/')
return identifier; // there is no BSD device name or it's a network path


// This section of code was liberally copied from the VolumeToBSDNode example project.

// Create a matching dictionary that will find the I/O Registry node corresponding to the volume.
CFMutableDictionaryRef matchingDict = IOBSDNameMatching(kIOMasterPortDefault,0,deviceName);
if (matchingDict==NULL)
return identifier; // could not create match criteria (unlikely)


io_service_t service;
service = IOServiceGetMatchingService(kIOMasterPortDefault,matchingDict);
if (service==IO_OBJECT_NULL)
return identifier; // this volume does not have an IOMedia node in the registry


// Create an iterator across all parents of the service object
kern_return_t kernResult;
io_iterator_t iter;
kernResult = IORegistryEntryCreateIterator(service,
kIOServicePlane,
kIORegistryIterateRecursively | kIORegistryIterateParents,
&iter);
if (kernResult!=KERN_SUCCESS || iter==IO_OBJECT_NULL)
return identifier; // unable to create iterator (unlikely)


    // Walk the I/O registry nodes looking for the whole media object
    Boolean isWholeMedia = false;
    do {
        if (IOObjectConformsTo(service,kIOMediaClass))
            {
            // Found an IOMedia node in the registry tree
            // See if it's a "whole" media node
            CFTypeRef wholeMedia;
            wholeMedia = IORegistryEntryCreateCFProperty(service,
                                                         CFSTR(kIOMediaWholeKey),
                                                         kCFAllocatorDefault,
                                                         0);
            if (wholeMedia!=NULL)
                {
                isWholeMedia = CFBooleanGetValue(wholeMedia);
                CFRelease(wholeMedia);
                }

if (isWholeMedia)
{
// Get the device name of the whole media node
CFTypeRef bsdName;
bsdName = IORegistryEntryCreateCFProperty(service,
CFSTR(kIOBSDNameKey),
kCFAllocatorDefault,
0);
if (bsdName!=NULL)
{
// Success! Return the drive's BSD device name as a string and exit
identifier = [(id)bsdName autorelease];
}
}
}
IOObjectRelease(service);
} while ( (service=IOIteratorNext(iter))!=IO_OBJECT_NULL && !isWholeMedia );
if (service!=IO_OBJECT_NULL)
IOObjectRelease(service);
IOObjectRelease(iter);


return identifier; // return the whole media device name, or the default (if while loop falls through)
}
--
James Bucanek


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: FSGetVolumeMountInfoSize returns error -36?
      • From: Chris Suter <email@hidden>
References: 
 >Re: FSGetVolumeMountInfoSize returns error -36? (From: Chris Suter <email@hidden>)

  • Prev by Date: Re: FSGetVolumeMountInfoSize returns error -36?
  • Next by Date: Re: FSGetVolumeMountInfoSize returns error -36?
  • Previous by thread: Re: FSGetVolumeMountInfoSize returns error -36?
  • Next by thread: Re: FSGetVolumeMountInfoSize returns error -36?
  • Index(es):
    • Date
    • Thread