Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hoptoad!tim From: tim@hoptoad.uucp (Tim Maroney) Newsgroups: comp.sys.mac.programmer Subject: Re: SFReply.vRefNum -> PathName Message-ID: <10161@hoptoad.uucp> Date: 10 Feb 90 20:47:37 GMT References: <11377@attctc.Dallas.TX.US> <9019@unix.SRI.COM> Reply-To: tim@hoptoad.UUCP (Tim Maroney) Organization: Eclectic Software, San Francisco Lines: 126 The Pascal source posted ignores errors and string lengths, and so it can easily crash your machine if the path name runs to more than 255 characters or if an error leaves directoryName with a large length byte. Here's some C code to do the same thing (MPW C 3.0, but since it was originally written in LSC 3.0 it shouldn't be hard to convert back). FullFileName should be passed an empty string in tail if you just want the name of a folder. SFVolDir(short wd, short *volume, long *folder) { WDPBRec pb; unsigned char name[72]; pb.ioNamePtr = (StringPtr)name; pb.ioVRefNum = wd; pb.ioWDIndex = 0; pb.ioWDProcID = 0; pb.ioWDVRefNum = 0; PBGetWDInfo(&pb, false); if (pb.ioResult) return pb.ioResult; *volume = pb.ioWDVRefNum; *folder = pb.ioWDDirID; return noErr; } FullFileName(StringPtr outname, StringPtr tail, short volume, long dirID) { StringHandle name; Str255 text, volname; HVolumeParam hvp; CInfoPBRec di; long size; short err; /* extract the volume name */ hvp.ioNamePtr = volname; hvp.ioVRefNum = volume; hvp.ioVolIndex = 0; PBHGetVInfo((HParmBlkPtr)&hvp, false); if (hvp.ioVSigWord == 0xd2d7) { outname[0] = 0; return noHFSerr; } /* create and initialize the name handle */ if (tail) { if (err = PtrToHand(tail + 1, &name, tail[0])) return err; size = tail[0]; } else { if ((name = NewHandle(0)) == 0) return MemError(); size = 0; } /* now start extracting the dirs and prepending them to * the handle */ for ( ; dirID != 2; dirID = di.dirInfo.ioDrParID) { text[0] = 0; di.dirInfo.ioNamePtr = text; di.dirInfo.ioVRefNum = volume; di.dirInfo.ioFDirIndex = -1; di.dirInfo.ioDrDirID = dirID; PBGetCatInfo(&di, false); text[++text[0]] = ':'; SetHandleSize(name, size += text[0]); BlockMove((Ptr)*name, (Ptr)(*name) + text[0], size - text[0]); BlockMove((Ptr)text + 1, (Ptr)*name, text[0]); } /* prepend the volume name onto the handle */ volname[++volname[0]] = ':'; SetHandleSize(name, size += volname[0]); BlockMove((Ptr)*name, (Ptr)(*name) + volname[0], size - volname[0]); BlockMove((Ptr)volname + 1, (Ptr)*name, volname[0]); /* copy and delete the handle */ if (size > 255) { DisposHandle(name); SysBeep(12); outname[0] = 0; return tooBigErr; } outname[0] = size; BlockMove((Ptr)*name, (Ptr)outname + 1, size); DisposHandle(name); return noErr; } And on the theory that you might want to convert the name back some day, here's a routine I use for that. Notice that it will actually create the directory if it doesn't exist now. If this isn't what you want, throw away the error recovery code. FullToFolder(StringPtr name, short *volume, long *folder) { CInfoPBRec dirInfo; HVolumeParam hvp; short i; dirInfo.dirInfo.ioNamePtr = name; dirInfo.dirInfo.ioDrDirID = 0; dirInfo.dirInfo.ioVRefNum = 0; dirInfo.dirInfo.ioFDirIndex = 0; if (PBGetCatInfo (&dirInfo, 0) == noErr) { if (dirInfo.dirInfo.ioFlAttrib & 0x10) { *folder = dirInfo.dirInfo.ioDrDirID; hvp.ioNamePtr = name; for (i = 0; i < name[0]; i++) if (name[i+1] == ':') { name[0] = i + 1; break; } hvp.ioVolIndex = -1; hvp.ioVRefNum = 0; PBHGetVInfo ((HParmBlkPtr)&hvp, 0); *volume = hvp.ioVRefNum; } else { *volume = 0, *folder = 0; return -1; } } else if (dirInfo.dirInfo.ioResult == fnfErr || dirInfo.dirInfo.ioResult == dirNFErr) { dirInfo.dirInfo.ioNamePtr = (StringPtr)name; dirInfo.dirInfo.ioDrDirID = 0; dirInfo.dirInfo.ioVRefNum = 0; if (PBDirCreate((HParmBlkPtr)&dirInfo, false) == noErr) { *volume = dirInfo.dirInfo.ioVRefNum; *folder = dirInfo.dirInfo.ioDrDirID; } else { *volume = 0, *folder = 0; return dirInfo.dirInfo.ioResult; } } else { *volume = 0, *folder = 0; return dirInfo.dirInfo.ioResult; } return noErr; } -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com "The time is gone, the song is over. Thought I'd something more to say." - Roger Waters, Time