cute@sphinx.uchicago.edu (John Cavallino) (07/16/87)
[Constructing full paths] Here is some pascal code which performs said useful function. If you like it, use it. It was developed in Lightspeed Pascal, and is known to work correctly on a 512kE, MacPlus and Mac SE. --- { some helpful HFS procedures and functions } { by John Cavallino } { last edit: 5-25-87 } FUNCTION HFS : boolean; { returns TRUE if we are running under HFS } CONST FSFCBLen = $3F6; { see Inside Mac., IV-309 } VAR FCBLen : ^integer; BEGIN FCBLen := pointer(FSFCBLen); HFS := (FCBLen^ > 0); END; { function HFS } FUNCTION BigDisk (vRefNum : integer) : boolean; { the function assumes it is running under HFS, } { else why would we want to check? } CONST BigDiskSig = $4244; { see Inside Mac., IV-166 } VAR vInfo : HParamBlockRec; err : integer; BEGIN WITH vInfo DO BEGIN ioCompletion := NIL; ioNamePtr := NIL; { we're not interested in the name } ioVRefNum := vRefNum; { this volume, please } ioVolIndex := 0; { look up using ioVRefNum only } END; err := PBHGetVInfo(@vInfo, false); IF (err = noErr) THEN BigDisk := (vInfo.ioVSigWord = BigDiskSig) ELSE BigDisk := false; END; { function BigDisk } FUNCTION BuildPath (VAR vRefNum : integer; fileName : Str31; DirID : longint; wdProc : longint; VAR path : Str255) : OSErr; { constructs the full path for the file, directory and volume specified } { If the path runs over 255 characters, it is truncated to a partial path and } { a WD reference (built with wdProc) to the root of the path is returned } { in vRefNum. If the path is complete, the original vRefNum value is returned } CONST rootID=2; VAR pInfo : CInfoPBRec; vInfo : ParamBlockRec; wdInfo : WDPBRec; dirName : Str255; theDir : longint; wdRef : integer; err : integer; MFS : boolean; done : boolean; tooLong : boolean; BEGIN IF HFS THEN MFS := NOT BigDisk(vRefNum) ELSE MFS := true; IF MFS THEN BEGIN { is MFS volume } dirName := ''; { initialize the name } WITH vInfo DO BEGIN ioCompletion := NIL; ioNamePtr := @dirName; { volume name is returned here } ioVRefNum := vRefNum; { this volume, please } ioVolIndex := 0; { use ioVRefNum only } END; err := PBGetVInfo(@vInfo, false); IF (err = noErr) THEN path := concat(dirName, ':', fileName) ELSE path := ''; END { is MFS volume } ELSE BEGIN { is HFS volume } path := fileName; done := false; tooLong := false; theDir := DirID; err := noErr; WHILE NOT done AND NOT tooLong AND (err = noErr) DO BEGIN dirName := ''; { initialize the name } WITH pInfo DO BEGIN ioCompletion := NIL; ioNamePtr := @dirName; { dir. name returned here } ioVRefNum := vRefNum; { this volume, please } ioFDirIndex := -1; { look at theDir only } ioDirID := theDir; { this directory please } END; err := PBGetCatInfo(@pInfo, false); IF (err = noErr) THEN IF (2 + length(dirName) + length(path)) > 255 THEN { the 2 is to allow for colons } tooLong := true ELSE BEGIN path := concat(dirName, ':', path); done := (pInfo.ioDirID = rootID); { are we at the root? } IF NOT done THEN theDir := pInfo.ioFlParID; { climb the tree } END; END; { while not done and not tooLong and (err = noErr) do } IF tooLong THEN BEGIN path := concat(':', path); { return partial path } WITH wdInfo DO BEGIN ioCompletion := NIL; ioNamePtr := NIL; { just initialize field } ioVRefNum := vRefNum; { on this volume, please } ioWDProcID := wdProc; { give it this procID } ioWDDirID := theDir; { it's this directory } END; err := PBOpenWD(@wdInfo, false); { build WD for root of path } IF (err = noErr) THEN vRefNum := wdInfo.ioVRefNum { WDRefNum returned in this field } ELSE BEGIN { no more working directories available } vRefNum := 0; path := ''; END; END; { if tooLong } END; { is HFS volume } BuildPath := err; { return the error code } END; { function BuildPath } ---