This article is from the Mac Programming FAQ, by Jon Watte h+@austin.metrowerks.com with numerous contributions by others.
Enter PBGetCatInfo, the Vegimatic of the Mac file system. Any Mac
hacker of knowledge has taken this system call to his heart. Note that
this sample code isn't all there, but should point you in the right
direction:
*code*
Boolean IsFolder(FSSpec *fs) // this function is called later
{
CInfoPBRec rec;
rec.hFileInfo.ioNamePtr = fs -> name;
rec.hFileInfo.ioVRefNum = fs -> vRefNum;
rec.hFileInfo.ioDirID = fs -> parID;
if ( !fs -> name [ 0 ] )
{
rec . hFileInfo . ioFDirIndex = 0 ;
} else
{
rec . hFileInfo . ioFDirIndex = -1 ;
}
rec . hFileInfo . ioFVersNum = 0 ;
PBGetCatInfoSync (&rec);
return(!rec.hFileInfo.ioFlAttrib & 0x10);
}
*end*
*code*
OSErr GetFolderParent(FSSpec *fss, FSSpec *parent)
{
CInfoPBRec rec;
short err;
*parent = *fss;
rec.hFileInfo.ioNamePtr = parent -> name ;
rec.hFileInfo.ioVRefNum = parent -> vRefNum ;
rec.hFileInfo.ioDirID = parent -> parID ;
if ( !parent -> name [ 0 ] ) // dougw -- neg of FAQ
{
rec . hFileInfo . ioFDirIndex = 0 ;
}
else
{
rec . hFileInfo . ioFDirIndex = -1 ;
}
rec . hFileInfo . ioFVersNum = 0 ;
err = PBGetCatInfoSync ( & rec ) ;
if ( ! ( rec . hFileInfo . ioFlAttrib & 0x10 ) ) { /* Not a folder */
if ( ! err ) {
err = dirNFErr ;
}
} else {
parent -> parID = rec . dirInfo . ioDrParID ;
BlockMove(rec.dirInfo.ioNamePtr, parent->name, rec.dirInfo.ioNamePtr[0]);
}
return err ;
}
*end*
*code*
OSErr GetFullPathHandle ( FSSpec * fss , Handle * h )
{
Handle tempH = NULL;
FSSpec fs = * fss ;
FSSpec sSpec;
if(*h == NULL) // allocate a handle if needed
{
*h = NewHandle(0);
}
while ( fs . parID > 1 )
{
tempH = NULL ;
PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
HandAndHand ( * h , tempH ) ;
SetHandleSize ( * h , 0L ) ;
HandAndHand ( tempH , * h ) ;
DisposeHandle ( tempH ) ;
tempH = NULL ;
GetFolderParent ( & fs , & sSpec ) ;
fs = sSpec ;
}
// fs should now contain info about the volume itself
PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
HandAndHand ( * h , tempH ) ;
SetHandleSize ( * h , 0L ) ;
HandAndHand ( tempH , * h ) ;
DisposeHandle ( tempH ) ;
tempH = NULL ;
if (!IsFolder ( fss ) )
{
SetHandleSize ( * h , GetHandleSize ( * h ) - 1 ) ;
}
DisposeHandle(tempH);
return 0 ;
}
*end*
 
Continue to: