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 }
---