mac-rom/OS/HFS/TFSDIR3.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

878 lines
38 KiB
Plaintext

;
; File: TFSDIR3.a
;
; Contains: This file contains routines using file names to specify file.
;
; Copyright: © 1982-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM3> 8/27/93 BH Removed <SM2>. The flushing stuff is now in CmdDone.
; <SM2> 8/3/93 BH Flushing critical volume info when changed for a volume in a
; manual-eject drive.
; <SM1> 4/1/92 kc Roll in SetFileLock patch from FileMgrPatches.a.
; ¥ Pre-SuperMario comments follow ¥
; <2> 9/12/91 JSM Add a header.
; <1.2> 3/2/89 DNF removed references to forROM; HFS now builds identically for ram
; or rom
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
; 1/14/87 BB Fixed GetFileInfo to return bad name error (BdNamErr) for a zero
; length name parameter (Bug #3819). NOTE: this is not patched for
; the Mac+ or MAUI.
; 9/24/86 BB Updated to use new MPW equates.
; 11/6/85 PWD Changed bits used for fork busy flags to 2 (resource fork) and 3
; (data fork)
; 10/29/85 LAK Vectored FndFilName.
; 10/27/85 PWD Changed _GetFileInfo to return separate busy bits for different
; forks of a file.
; 10/8/85 PWD Fixed to call correct MFS entry point (SetMFlType)
; 10/1/85 LAK Removed convert of internal errors to TFDSIntErr.
; 9/25/85 PWD Changed to skip PMSP if filename contains directory spec. in
; FndFilName.
; 9/25/85 PWD Fixed FndFilName to check for root directory before moving up in
; directory hierarchy, changed GetCatInfo to do complete DirID
; determination before checking for volume-type (to allow MFS
; VRefNum used as sole argument to return directory info)
; 9/24/85 PWD Removed code to set clump size in SetCatInfo
; 9/8/85 LAK Modified CkFilMod so it doesn't use FSTemp4.
; 9/6/85 LAK Clear IORefNum before calling CkFileBusy for GetFile/Cat/Info.
; For MFS volumes, SetCatInfo is now the same as SetFileInfo.
; 8/28/85 LAK Cleaned up FndFilName a bit (short branches added).
; 8/22/85 PWD Changed GetFileInfo/GetCatInfo to skip PMSP when using FileIndex
; 6/20/85 PWD Changed to use new system CNode equates
; 6/19/85 PWD Changed internal errors to FSDSIntErr instead of IOErr.
; 5/9/85 PWD Changed GetCatInfo to return fake information for root directory
; on MFS volumes to simplify enumeration
; 5/9/85 PWD Changed to check TFS dir. entry type before acting
; 5/1/85 PWD Added GetCatInfo and SetCatInfo; changed GetFileInfo to clear
; ioDirFlg bit in ioFlAttrb.
; 4/26/85 PWD Changed to use expanded Finder info field
; 4/25/85 PWD Changed to convert all internal errors to IOErr.
; 4/22/85 PWD Fixed GetFileName enumeration to use VCBDirIndex field.
; 4/14/85 LAK Added RAM patch for GetCatInfo/GetFileInfo (VCBDirIndex field is
; invalid after an indexed GetCatInfo call). Removed clear of this
; field for GetCatInfo by name. This all should really be handled
; by the Catalog manager: it should have a separate call which
; gets indexed cnode skipping directories).
; 3/10/85 PWD Changed to use TFS catalog structure for TFS volumes
; 2/28/85 PWD Moved MFS-specific code into MFSDir3. Changed FndFilName to
; parse TFS filenames for TFS volumes.
; 7/9/84 GSS Patched SetFileInfo to write out creation and modification date
; info.
; 9/1/83 LAK Changed BPL to BCC in file name transfer to support file names >
; 127 chars in GetFileInfo.
; 8/31/83 LAK Changed GetFileInfo to return current file info for opened files
; (from FCB information).
; 6/6/83 LAK Added changes to support ext fs, offline volumes.
; 6/6/83 LAK Changed to use CkFilMod subroutine.
; 5/25/83 LAK Adapted FndFilName to new CmpString interface.
; 1/16/83 LAK Final pass changes . . . added SetFilLock,RstFilLock,SetFilType.
; 1/16/83 LAK New today.
; 12/14/82 LAK Undelete removal changes
; 12/13/82 LAK Reworked all files for new file system data structures.
; 1/12/82 LAK Made string compare proc an OS call; code is in IOCore.
;
;_______________________________________________________________________
;
; External Routines: GetFileInfo,SetFileInfo, Get/SetCatInfo
;
; Internal Routines: CkFilMod,FndFilName,GetCurB1,ExtOffLinCk
;
;_______________________________________________________________________
;_______________________________________________________________________
;
; Routine: SetFilType
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to I/O parameter block, uses
; IOFileName,IODrvNum,IOFileType,IONewType
; D0.W (output) -- 0 if file was found and set correctly.
; Calls: FndFilName
; Function: Set the directory type field for a file. The directory is first
; searched for a file with the same name and new type fields to
; avoid naming conflicts.
;
; Modification History:
; 16 Jan 83 LAK New today.
; 06 Jun 83 LAK Changed to use CkFilMod subroutine.
; 10 Mar 85 PWD Changed to use TFS catalog structure for TFS volumes
; 9 May 85 PWD Changed to check TFS dir. entry type before acting
; 8 Oct 85 PWD Fixed to call correct MFS entry point (SetMFlType)
;_______________________________________________________________________
SetFilType:
BLANKS ON
STRING ASIS
BSR FSQueue ; wait our turn
MOVE.B IOFileType(A0),D1 ; save original type
MOVE.B IONewType(A0),IOFileType(A0) ; set for destination type
BSR FndFilName ; does it exist already?
MOVE.B D1,IOFileType(A0) ; (restore original state)
TST.W D0 ; Re-check condition codes from FndFilName
BNE.S @1 ; br on error (incl not fnd)
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BEQ.S @2 ; If so, let it slide until CkFilMod <18Oct85>
MOVEQ #DupFNErr,D0 ; duplicate file name if found
@1 CMP.W #FNFErr,D0 ; file should not have been found
BNE.S SRFLXit3 ; br if not ok (also ext fs, offline errs)
BSR CkFilMod ; look for file and see if we can mod it
; (doesn't return on errors)
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE SetMFlType ; No - handle MFS dir. entry <PWD 08Oct85>
@2 MOVEQ #ParamErr,D0 ; If we didn't find it yet, there's no hope
BRA.S SRFLXit3 ; Exit
;_______________________________________________________________________
;
; Routine: SetFilLock, RstFilLock
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to I/O parameter block, uses
; IOFileName,IOFileType,IODrvNum
; D0.W (output) -- 0 if file was found and set correctly.
; Calls: FndFilName
; Function: Set or reset the file lock bit.
;
; Modification History:
; 16 Jan 83 LAK New today.
; 06 Jun 83 LAK Broke out CkFilMod as a subroutine.
; 10 Mar 85 PWD Modified for use with TFS catalog entries
;
; Note: if the file is locked after it has already been opened with write
; permission, the lock will not affect that opened file. If the lock bit
; is not changed by this command, the directory buffer is not marked dirty
; (allows quick lock/unlocking of a group of file, regardless of their current
; status).
;_______________________________________________________________________
SetFilLock:
BSR FSQueue ; wait our turn
ST FLckUnlck ; want to lock it
BRA.S SRFLck
RstFilLock:
BSR FSQueue
CLR.B FLckUnlck
SRFLck BSR CkFilMod ; look for file and see if we can mod it
; (doesn't return on errors)
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE ChgMFlLock ; Nope - do it the old fashioned way
MOVEQ #FNFErr,D0 ; Expect the worst
CMP.B #cdrFilRec,cdrType(A5) ; Is this a file entry?
BNE.S SRFLXit3 ; No - don't touch it
TST.B FLckUnlck ; Yes! Now, what was it we wanted?
BEQ.S @1 ; br if we want to unlock it
BSET #FilWrtFlag,FilFlags(A5) ; lock it
BNE.S SRFLXit2 ; br if already locked
ori.b #xFFFilAttrLockMask, filFndrInfo+fdXFlags(a5) ; set bits in fdXFlags <28Jun90> <SM1>
BRA.S SRFLXit1 ; otherwise, it's been modified
@1 BCLR #FilWrtFlag,FilFlags(A5) ; unlock it
BEQ.S SRFLXit2 ; br if already unlocked
andi.b #~xFFFilAttrLockMask, filFndrInfo+fdXFlags(a5) ; clear bits in fdXFlags <28Jun90> <SM1>
; Mark the buffer holding the catalog entry dirty:
SRFLXit1 MOVE.L D7,D2 ; Get a hold of the catalog hint
JSR CMUpdateCN ; Update the Catalog buffer
BRA.S SRFLXit3 ; If EQ, we're all set.
SRFLXit2 MOVEQ #0,D0
SRFLXit3 BRA CmdDone
;_______________________________________________________________________
;
; Routine: SetFileInfo
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to File Info I/O parameter block, uses
; IOFileName,IOFlAttrib,IOFlUsrWds
; D0.W (output) -- 0 if entry was found, error code otherwise
; File's entry is modified to reflect changes
; Calls: FndFilName
; Function: Sets the user-definable fields in a file's directory entry.
; The caller specifies the filename and type, and the eight
; user-defined words. The file lock bit does not inhibit this
; command.
;
; Modification History:
; 13 Dec 82 LAK Modified for new file system data structures.
; 17 Jan 83 LAK Latest changes: no longer used to change lock, type fields;
; there are now 16 user-defined bytes.
; 06 Jun 83 LAK Adapted to new offline, ext fs problems. Uses CkFilMod
; and SRFLXit1 to save code.
; 09 Jul 84 GSS Patched to write out creation and modification date info
; 13 Mar 85 PWD Separated out MFS code; added TFS support
; 26-Apr-85 PWD Changed to use expanded Finder info field
;_______________________________________________________________________
SetFileInfo:
BSR FSQueue ; wait our turn
BSR CkFilMod ; look for modifiable file
; (doesn't return on errors)
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE SetMFlInfo ; If not, leave it to the MFS code
MOVEQ #FNFErr,D0 ; Expect the worst
CMP.B #cdrFilRec,cdrType(A5) ; Is this a file entry?
BNE.S SRFLXit3 ; No - don't touch it
MOVEM.L IOFlUsrWds(A0),D1-D4 ; get 16 bytes of Finder Info
MOVEM.L D1-D4,FilUsrWds(A5) ; transfer 16 finder bytes
MOVEM.L IOFlCrDat(A0),D1-D2 ; get IOFlCrDat, IOFlMdDat
MOVEM.L D1-D2,FilCrDat(A5) ; and store in FilCrDat, FilMdDat
BRA.S SRFLXit1 ; exit ok, marking buffer modified
;_______________________________________________________________________
;
; Routine: SetCatInfo
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to File Info I/O parameter block, uses
; IOFileName,IOFlAttrib,IOFlUsrWds,IOFlFndrInfo
; D0.W (output) -- 0 if entry was found, error code otherwise
; File's entry is modified to reflect changes
; Calls: FndFilName
; Function: Sets the user-definable fields in a file's catalog entry.
; The caller specifies the filename and type, the sixteen
; user-defined bytes, and the 32 bytes of Finder Info.
; The file lock bit does not inhibit this command.
;
; Modification History:
; 1-May-85 PWD New today.
; 9-Aug-85 PWD Added code to support file Clump Size attributes.
; <06Sep85> LAK For MFS volumes, it's now the same as SetFileInfo.
; 24-Sep-85 PWD Removed code to set clump size
;_______________________________________________________________________
SetCatInfo:
BSR FSQueue ; Wait our turn
BSR.S CkFilMod ; look for modifiable file
; (doesn't return on errors)
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE SetMFlInfo ; If not,same as SetFileInfo for MFS. <06Sep85>
CMP.B #cdrFilRec,cdrType(A5) ; Is this a file we're dealing with?
BNE.S @10 ; Nope - check for directory
; MOVE.L ioFlClpSiz(A0),D0 ; Pick up new clump size in bytes <24Sep85>
; DIVU VCBAlBlkSiz+2(A2),D1 ; Pick up allocation block size <24Sep85>
; BSR DivUp ; Divide, rounding up <24Sep85>
; MOVE.W D0,FilClpSize(A5) ; Set new clump size in al. blks. <24Sep85>
MOVEM.L IOFlUsrWds(A0),D0-D3 ; get 16 bytes of user info
MOVEM.L D0-D3,FilUsrWds(A5) ; transfer 16 user info bytes
MOVEM.L ioFlxFndrInfo(A0),D0-D3 ; Get 16 bytes of additional finder info <24Sep86>
MOVEM.L D0-D3,FilFndrInfo(A5) ; and copy them into the catalog entry
MOVEM.L IOFlCrDat(A0),D0-D1 ; Pick up creation & modification times
MOVEM.L D0-D1,FilCrDat(A5) ; Set new for entry
MOVE.L IOFlBkDat(A0),FilBkDat(A5) ; New backup date
BRA.S @90
@10 MOVEQ #BdNamErr,D0 ; Expect the worst
CMP.B #cdrDirRec,cdrType(A5) ; Is it a directory?
BNE.S SetCatIExit ; Nope - give up.
MOVEM.L IOFlUsrWds(A0),D1-D4 ; get 16 bytes of user info
MOVEM.L D1-D4,DirUsrInfo(A5) ; transfer 16 user info bytes
MOVEM.L ioFlxFndrInfo(A0),D0-D3 ; Get 16 bytes of finder info <24Sep86>
MOVEM.L D0-D3,DirFndrInfo(A5) ; and copy them into the catalog entry
MOVEM.L IODrCrDat(A0),D0-D2 ; Pick up create, mod, backup times
MOVEM.L D0-D2,DirCrDat(A5) ; Set new information for entry
@90 MOVEQ #0,D0 ; Indicate a successful completion
SetCatIExit BRA SRFLXit1 ; exit ok, marking buffer modified
; short code-saving routine called by Delete, SetFilType, SRFLck, SetFileInfo
CkFilMod:
MOVE.L (SP)+,-(A6) ; Save return address (FndFilName is async) <08Sep85>
BSR.S FndFilName ; find the file in the directory
BNE.S @1 ; exit if error (also ext fs, offline vols) <08Sep85>
BSR CVFlgs ; see if we can change it
BNE.S @1 ; exit if locked or write-protected <08Sep85>
MOVE.L (A6)+,-(SP) ; restore return address <08Sep85>
RTS ; and go there . . . <08Sep85>
@1 ADDQ #4,A6 ; don't return to caller <08Sep85>
BRA CmdDone ; <08Sep85>
;_______________________________________________________________________
;
; Routine: FndFilName,FndFN2
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to I/O parameter block, uses:
; IOFileName,IOFileType,IODrvNum
; D0.W (output) -- 0 if file was found, error code otherwise.
; D2.L (output) -- name length excluding any volume prefix
; A1.L (output) -- points to volume buffer (if name found)
; A2.L (output) -- pointer to appropriate VCB
; A3.L (output) -- pointer to WDCB, or nil if none specified
; A4.L (output) -- pointer to input file name.
; A5.L (output) -- pointer to file directory entry in buffer.
;
; TFS volumes only:
; D6.L (in/out) -- DirID of directory containing file
; D7.L (in/out) -- Catalog hint
;
; Preserves: D1,D5,A0
; Clobbers: all other registers (D3,D4,D6,D7,A3,A6)
; Note that the routine will return to one level above
; caller during the asynchronous reads.
; FndFN2 entry point for Rename (alternate volume may be used)
; Calls: DtrmVol,MyReadDB(via Rd1stDB and RdNxtDB)
; Called By: Create,Delete,FileOpen,Rename,GetFileInfo,SetFileInfo
; Function: Locate a filename within the directory on a diskette
; Search algorithm: if dir blk there, search it first;
; if not found, start from beginning, skipping searched blk.
;
; Modification History:
; 08 Dec 82 LAK Added FndFilName entry point.
; 13 Dec 82 LAK Rewrote. Removed index search mode.
; 14 Dec 82 LAK Removed check for delete file.
; 17 Jan 83 LAK Changes for last data structure mods: now checks for both
; filename and filetype match.
; 05 Jun 83 LAK Added checks for offline volume, external file system vols
; 28 Sep 84 GSS Inserted patch for setting ReqstVol in ExtOffLinCk
; (from CDHook in MSFileFix)
; 28-Feb-85 PWD Changed to parse TFS pathnames and return directory info
; in D6-D7.
; 14-Mar-85 PWD Changed to allow lookup of Directory CNodes (caller must
; check cdrType(A5) on return).
; 9-May-85 PWD Changed to interpret '::' in filename specs. Zero-length
; filename specs are OK on TFS volumes now (refers to Dir entry)
; Changed to ignore ioDirID when full pathname is specified (by
; semi-ultra-grosso kludge)
; 25-Sep-85 PWD Fixed to check for root directory before moving up to parent dir
; 25-Sep-85 PWD Changed to skip PMSP if filename contains directory spec.
;_______________________________________________________________________
FndFilName:
MOVE.L jFndFilName,-(SP) ; jumptable entry for vFndFilName <29Oct85>
RTS ; go there <29Oct85>
vFndFilName ; 'vectored' FndFilName routine <29Oct85>
BSR DtrmV3 ; determine the volume to be used
BEQ.S FndWDChk ; Check for WDCBs if vol. is determined
FndFNRTS RTS ; exit on vol errs
FndWDChk MOVEQ #FSRtDirID,D6 ; Default to root.
MOVE.L A3,D7 ; Get WDCB pointer, if any
BEQ.S @2 ; If it's zero, we're all set <28Aug85>
;
; The user specified a WDCB:
;
MOVE.L WDDirID(A3),D6 ; Retrieve Directory ID in WDCB
MOVE.L WDCatHint(A3),D7 ; Catalog node hint.
;
; Compute the length of the volume name removed from the head of the original
; file name: if non-zero, ignore the DirID specified, and use the root DirID.
;
@2 MOVE.L A4,D0 ; Examine new name pointer
BEQ.S @3 ; If nil, none was specified <28Aug85>
SUB.L IOFileName(A0),D0 ; Subtract original pointer
SUBQ.L #2,D0 ; Subtract out length byte & colon
BGT.S FndFN2 ; If resulting length >0, volname was found <28Aug85>
@3 BTST #HFSBit,IOTrap(A0) ; Are TFS arguments specified?
BEQ.S FndFN2 ; If not, this is it. <28Aug85>
MOVE.L IODirID(A0),D0 ; Otherwise, this might be the DirID
BEQ.S FndFN2 ; But it'd better be non-zero <28Aug85>
MOVE.L D0,D6 ; This one's for real, though
MOVEQ #0,D7 ; no B*-Tree hint known
;
; The FndFN2 entry point requires the caller to've set up:
; A0.L - I/O Parameter block
; A2.L - VCB pointer
; D2,A4 - File name string
; D6,D7 - DirID and catalog hint (TFS Volumes only)
;
FndFN2 BSR ExtOffLinCk ; make sure it's online, internal fs
BNE.S FndFNRTS ; Give up now if it isn't
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE FndMFSFile ; If not, leave it to the MFS code
;
; If we've come this far, we're dealing with a TFS volume, requiring delicate
; pathname parsing and working-directory consideration.
;
MOVE.L (SP)+,-(A6) ; Save return address on TFS stack
MOVEM.L D1/A0-A1,-(A6) ; Save registers
;;; MOVEQ #BdNamErr,D0 ; Assume bad file name
MOVE.L D2,D1 ; Set up copy for restoration on errors
;;; BEQ FndFNExit ; Skip out on zero length files
MOVE.L D2,D4 ; Save name length (not incl. vol. name)
;
; Scan the name string for the first element in the pathname:
;
@1 MOVEQ #DirNFErr,D0 ; Assume we're looking for a directory
MOVEQ #0,D1 ; Start at start
@2 MOVEQ #0,D3 ; Clear 'empty-PN-elmt' flag
CMP.W D4,D1 ; Check against available length
BGE.S @5 ; If exceeded, that's full name scanned <28Aug85>
CMP.B #':',0(A4,D1) ; Hit a separator?
BEQ.S @3 ; If so, it's the end of a pathname elmt. <28Aug85>
CMP.W #31,D1 ; Already collected 31 characters (max)?
BLT.S @25 ; If not, continue
MOVEQ #BdNamErr,D0 ; Otherwise, we're up the creek
BRA FndFNErr ; So Punt.
;
@25 ADDQ.W #1,D1 ; Adavance the string pointer
BRA.S @2 ; And check the next character <28Aug85>
@3 BSET #SkipPMSP,HFSFlags ; If there's a colon in the file name <25Sep85>
; that wasn't part of the vol spec, skip <25Sep85>
; any PMSP trouble. <25Sep85>
TST.W D1 ; Check: just scan an empty PN elmt?
SEQ D3 ; Set flag to indicate parent req.
SWAP D3 ; Hide flag for a sec
MOVE.W D4,D3 ; Copy for a quick check
SUB.W D1,D3 ; Subtract out length so far
SUBQ.W #1,D3 ; Including colon
BGT.S @6 ; If something left, we're OK
@5 MOVEQ #FNFErr,D0 ; Last PN elmt: no need to try again
@6 SWAP D3 ; Restore empty PN elmt flag
MOVEM.L D6-D7,-(A6) ; Copy DirID and Catalog hint onto stack
MOVEM.L D0/A1,-(SP) ; Save 'em through this little manouver
MOVEA.L D1,A0 ; Save string length
ADDQ.W #1,D1 ; Prepare to round length up: add one
LSR.W #1,D1 ; Divide by two
LSL.W #1,D1 ; And multiply back to rounded value
SUBA.L D1,A6 ; Allocate room for string on stack
MOVE.L D1,-(SP) ; Stash 'fixed' length on stack
MOVE.L A0,D1 ; Restore original length
;
; Copy the name string:
;
MOVEA.L A4,A0 ; Point to source string start
MOVEA.L A6,A1 ; Point to target string start
MOVE.L D1,D0 ; String length for _BlockMove
_BlockMove
MOVE.W D1,-(A6) ; Push length in front of new string
MOVE.L (SP)+,D1 ; Set D1 to 'fixed' length
MOVEA.L A6,A0 ; Point to element name
ADDQ.L #1,A0 ; Length actually starts in low byte
MOVEM.L (SP)+,D0/A1 ; Restore scratch registers
EXG D6,D0 ; Put DirID in D0, err. code in D6
MOVE.L D7,D2 ; Catalog hint
JSR CMGetCN ; Try to retrieve the CNode.
;
; Now to remove this junk from the A6 stack again:
;
MOVE.W (A6)+,-(SP) ; Stash real length word
ADDA.L D1,A6 ; Adjust for string contents+length word
MOVEQ #0,D1 ; Clear top half of D1
MOVE.W (SP)+,D1 ; Retrieve the true string length
TST.W D0 ; Now then, any errors?
BNE.S @20 ; Examine errors carefully <28Aug85>
TST.B D3 ; Time to move up in the world?
BEQ.S @8 ; Nope - just keep on truckin' <28Aug85>
;
; We're parsing an empty pathname element: the previous search for <dir>'' must
; have led us to the directory descriptor for <dir> in its parent: to continue
; the search in the parent directory, we must recover the directory entry for the
; parent directory ITSELF, which can be found from the parent ID and a null CName
; (a NIL pointer will do, courtecy CMSvcs):
;
MOVEQ #DirNFErr,D0 ; Start out pessimistically <25Sep85>
CMP.L #FSRtParID,CKRParID(A0) ; Are we already looking at the root? <25Sep85>
BEQ.S @20 ; If so, our worst fears were just realized <25Sep85>
MOVE.L CKRParID(A0),D0 ; Otherwise, go look up the parent directory<25Sep85>
MOVEQ #0,D2 ; No hint.
SUBA.L A0,A0 ; No CName
JSR CMGetCN ; Find the parent directory entry back
BNE.S @20 ; Examine errors carefully <28Aug85>
MOVE.L CKRParID(A0),D0 ; Set up D0 as parent directory
MOVEQ #0,D2 ; No known hint.
@8 CMP.W #FNFErr,D6 ; Were we looking for a file?
BEQ.S @10 ; If so, we've just found our man! <28Aug85>
;
; Retrieve the directory information from the directory CNode:
;
MOVEM.L (A6)+,D6-D7 ; Discard the old DirID and Cat. hint
MOVE.L DIRDirID(A1),D6 ; This directory's directory ID
MOVE.L D2,D7 ; Catalog hint
;
; Continue the pathname scan with the next pathname element:
;
ADDQ.W #1,D1 ; Advance beyond separator
ADDA.L D1,A4 ; Advance string pointer to next element
SUB.W D1,D4 ; Reduce length by length of first elmt.
BRA @1 ; Continue the scan
;
; The last element on the path was successfully found:
;
@10 MOVEQ #0,D0 ; All is well.
MOVEA.L A1,A5 ; Point to catalog record
MOVE.L D2,4(A6) ; Update catalog hint still on A6 stack
BRA.S @40
@20 CMP.W #CMNotFound,D0 ; Did we miss a CNode?
BNE.S @40 ; Nope - something else went wrong <28Aug85>
MOVE.L D6,D0 ; Fill in appropriate message
@40 MOVEM.L (A6)+,D6-D7 ; Restore last DirID and Catalog hint
FNDFNExit MOVE.L D1,D2 ; Restore file name length
FNDFNErr MOVEM.L (A6)+,D1/A0-A1 ;
MOVE.L (A6)+,-(SP) ; Restore return address
TST.W D0 ; Set condition codes
RTS
; short routine to save code (used by GetFilInfo, FndFilName)
ExtOffLinCk BSR CkExtFS ; is this VCB for us?
BNE.S @1 ; br if not
TST.W VCBDrvNum(A2) ; volume offline?
BNE.S @1 ; br if not
MOVEQ #VolOffLinErr,D0 ; otherwise, note the error
@1 MOVE.L A2, ReqstVol
TST.W D0
RTS
;_______________________________________________________________________
;
; Routine: GetFileInfo
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to File Info I/O parameter block, uses
; all fields?
; D0.W (output) -- 0 if info was found, error code otherwise
; Calls: FndFilName(if searching by name)
; Function: Get information about a specific file from the file directory.
; User can specify search by either filename or by index,
; where the index specifies the file's offset from the beginning
; of the directory.
;
; An index of zero means search by filename and type.
;
; Modification History:
; 10 Dec 82 LAK Modified for new file system data structures.
; 13 Dec 82 LAK Removed delete file support.
; 17 Jan 83 LAK Another passover.
; 06 Jun 83 LAK Added changes to detect offline volumes, ext fs calls.
; 01 Sep 83 LAK Changed BPL to BCC in file name transfer to support file
; names > 127 chars.
; 10 Mar 85 PWD Changed to search catalog for TFS volumes
; 22 Apr 85 PWD Changed to shortcut enumeration by looking at VCBDirIndex and
; catalog manager's VCBDirIDM and VCBOffsM.
; 9 May 85 PWD Changed GetCatInfo to construct fake root directory for MFS volumes
; 22-Aug-85 PWD Changed to not use PMSP when searching by index.
; 21-Sep-85 PWD Changed to allow general 'volume name:' spec. by constructing a
; fake root entry for MFS volumes.
; <27Oct85> PWD Changed to return separate busy bits for different forks of a file.
; <06Nov85> PWD Changed bits used for flags above to 2 (resource fork) and 3 (data fork)
;_______________________________________________________________________
GetCatInfo:
BSR FSQueue ; Wait our turn
BSET #HFSReq,HFSFlags ; Request full catalog information
TST.W IOFDirIndex(A0) ; Check the index:
BMI.S GetDirInfo ; If <0, look up directory information
BRA.S FndCatEntry ; Go look up the requested entry
GetFileInfo:
BSR FSQueue ; Wait our turn
BCLR #HFSReq,HFSFlags ; don't return full catalog info
FndCatEntry MOVE.W IOFDirIndex(A0),D1 ; get file index, if there is one
BGT.S GFIByIndx ; If >0, look by index
BSR FndFilName ; search by name for file or dir.
BEQ.S @1 ; Continue if all was well <21Sep85>
CMP.W #BdNamErr,D0 ; Bad file name returned? <21Sep85>
BNE GFIExit ; exit if not found, offline, ext fs <21Sep85>
TST.B D2 ; Zero-length name? <21Sep85>
BNE GFIExit ; Nope - error's for real <21Sep85>
BTST #HFSReq,HFSFlags ; GetCatInfo call? <14Jan87>
BNE.S fakeRoot ; Yes - contruct a fake root entry <14Jan87>
BRA GFIExit ; No - return bad name error <14Jan87>
@1 BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BNE GetMFlInfo ; If not, leave it to the old code
MOVE.L D6,D1 ; Save parent's directory ID
BRA XferFInfo ; br if not searching by index
GetDirInfo MOVEQ #0,D1 ; Indicate directory itself is wanted
GFIByIndx BSET #SkipPMSP,HFSFlags ; Don't try any search path stuff here <22Aug85>
BSR DtrmV1 ; figure volume from drvnum/vrefnum
BNE GFIExit ; Punt on errors
BSR.S ExtOffLinCk ; make sure it's on-line, internal fs
BNE GFIExit
; Determine the directory of choice: <25Sep85>
; .
dtrmDir MOVEQ #FSRtDirID,D6 ; Default is root DirID .
MOVE.L A3,D7 ; WDCB specified? (may clear hint) .
BEQ.S @3 ; If none specified, we're all set.
MOVE.L WDDirID(A3),D6 ; Pick up the directory from the WDCB
MOVE.L WDCatHint(A3),D7 ; And use the catalog hint supplied there
@3 BTST #HFSBit,ioTrap(A0) ; TFS bit set on trap word?
BEQ.S @10 ; Nope - good thing we've got defaults
TST.L ioDirID(A0) ; User specified directory
BEQ.S @10 ; If not, we're set
@5 MOVE.L ioDirID(A0),D6 ; Set DirID of choice
MOVEQ #0,D7 ; No hint known for this DirID .
; .
@10 BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BEQ.S retDirInfo ; Yes: there's a real catalog: go for it<25Sep85>
; We were asked for information on an MFS volume:
rootCheck MOVEQ #DirNFErr,D0 ; Prepare for the worst <25Sep85>
CMP.L #FSRtDirID,D6 ; Can we fake it? <25Sep85>
BNE GFIExit ; No - fail miserably <25Sep85>
TST.W D1 ; Check the directory index <25Sep85>
BGT GtMFlIBI ; If >0, MFS code will find the file <25Sep85>
; Zero the return information area, mostly to zero some non-existant fields
; (i.e. ioDrUsrInfo, ioDrFndrInfo, ioDrBkDat):
fakeRoot LEA ioFlAttrib(A0),A1 ; Clear the return information
MOVEQ #(ioHFQElSiz-ioFlAttrib)/2-1,D0 ; Number of words to clear <24Sep86>
@0 CLR.W (A1)+ ; Clear a word in the return info
DBRA D0,@0 ; until all's clear
BSET #ioDirFlg,ioFlAttrib(A0) ; Set directory bit in attributes
MOVE.L #FSRtDirID,ioDrDirID(A0) ; Fake directory ID
MOVE.L #FSRtParID,ioDrParID(A0) ; Fake parent ID
;
; Pick up some of the information from the VCB:
;
MOVE.W VCBNmFls(A2),ioDrNmFls(A0) ; Number of directory entries
MOVE.L VCBCrDate(A2),ioDrCrDat(A0) ; Creation date
MOVE.L VCBLsMod(A2),ioDrMdDat(A0) ; Modification date
MOVE.L ioFileName(A0),D0 ; File name specified?
BEQ.S GFIOK ; If not, we're done
TST.W ioFDirIndex(A0) ; Asking for directory info by DirID? <25Sep85>
BEQ.S GFIOK ; If not, we're all set. <25Sep85>
MOVEA.L D0,A1 ; Make it the dest. of _BlockMove
LEA VCBVN(A2),A0 ; Source name is in VCB
MOVEQ #1,D0 ; Clear top 3 bytes, add one for length byte <29Aug85>
ADD.B (A0),D0 ; Pick up length to copy
_BlockMove ; Copy volume name
GFIOK MOVEQ #0,D0 ; Indicate complete success
BRA.S GFIExit ; All done!
; we are searching by index here: it's a bit tricky since the directory may
; contain directory nodes, which should be ignored on non-catalog calls, and we'd
; like to continue the search from the last one if at all possible:
retDirInfo
MOVEQ #FSRtParID,D0 ; Asking about the root parent? <01Oct85>
CMP.L D0,D6 ; <01Oct85>
BEQ.S GFInfErr ; If so, fail miserably
TST.W D1 ; Looking for directory itself?
BNE.S @13 ; Nope - go look by index
MOVEM.L A0-A1,-(A6) ; Store CMGetCN's output registers
MOVE.L D6,D0 ; DirID of choice
MOVE.L D7,D2 ; Directory hint
SUBA.L A0,A0 ; Clear CName
JSR CMGetCN ; Look up the directory information
BNE.S LookupErr ; Punt on errors
MOVE.L D2,D7 ; Save the hint
BRA.S GotIndFile ; Go return the directory information
@13 BTST #HFSReq,HFSFlags ; Requesting normal catalog treatment?
BNE.S GetCatOff ; If so, go read it directly
MOVE.W D1,D5 ; Stash directory index for later reference
MOVE.W VCBOffsM(A2),D1 ; Get last search's catalog offset
CMP.L VCBDirIDM(A2),D6 ; Same directory as last search?
BNE.S @15 ; If not, start afresh
CMP.W VCBDirIndex(A2),D5 ; Are we looking for file beyond this one?
BCS.S @15 ; If we're backing up, start afresh
MOVE.W VCBDirIndex(A2),D0 ; Otherwise, hold last DirIndex for later offset
MOVE.W D5,VCBDirIndex(A2) ; Set this up for future reference
SUB.W D0,D5 ; Skip to where we last left off
BRA.S @19 ; And start search at last offset
@15 MOVEQ #1,D1 ; Start with the first catalog offset
MOVE.W D5,VCBDirIndex(A2) ; Set up current file index for later
SUBQ #1,D5 ; #files to skip = index - 1
@19 MOVEM.L A0-A1,-(A6) ; Save CMGetOff's output registers
@20 MOVE.L D6,D0 ; Set up DirID for lookup
MOVE.L D7,D2 ; Accompanying catalog hint
SUBA.L A0,A0 ; No CNode specified
JSR CMGetOff ; Look up the indicated CNode
BNE.S LookupErr ; Fail miserably
MOVE.L D2,D7 ; Save catalog hint
ADDQ.W #1,D1 ; Look for next dir. entry
CMP.B #CDRFilRec,CDRType(A1) ; Did we find a file?
BNE.S @20 ; If not, just keep looking
DBRA D5,@20 ; Count down: 1 file skipped
BRA.S GotIndFile ; And show some results for our efforts
LookupErr MOVEM.L (A6)+,A0-A1 ; Restore originals
CMP.W #CMNotFound,D0 ; Did we just miss it?
BNE.S GFIExit ; Br if not. Otherwise, it's an FNFErr.
GFINFErr MOVEQ #FNFErr,D0 ; file not found . . . hmmmm
GFIExit BRA CmdDone
;
; We're handling a GetCatInfo request by index: D1 is already set up with
; the requested file index:
;
GetCatOff MOVEM.L A0/A1,-(A6) ; Save CMGetOff's output registers
; (1) CMGetOff is called from exactly two places: both in GetCatInfo.
; (2) CMGetOff is the only place where VCBDirIDM is validated.
; (3) The first GetCatInfo call to CMGetOff is for an indexed GetFileInfo call
; in which only files are wanted. VCBDirIndex is used here to keep
; a separate index marker for files. If VCBDirIDM is validated
; in this path, it is cool.
; (4) This second GetCatInfo call to CMGetOff is for a real indexed GetCatInfo
; call. If VCBDirIDM is validated in this path, VCBDirIndex should
; be invalidated.
; (5) VCBDirIndex can not be invalidated by setting it to zero: this makes
; it look valid always. By setting it to $FFFF, it will appear that
; any other indexed call is looking for a file before it and will
; thus be invalidated.
MOVE.W #-1,VCBDirIndex(A2) ; DirIndex will now be invalid <14Apr85>
MOVE.L D6,D0 ; DirID of choice
MOVE.L D7,D2 ; Accompanying catalog hint
SUBA.L A0,A0 ; No CName specified
JSR CMGetOff ; Look up the requested entry
BNE.S LookupErr
GotIndFile
; searched by index, so return the name . . .
LEA CKRCName(A0),A3 ; file entry name ptr
MOVE.L CKRParID(A0),D1 ; Save parent directory ID
MOVEA.L A1,A5 ; Point to catalog entry
MOVEM.L (A6)+,A0-A1 ; Restore the originals
MOVE.L IOFileName(A0),D0 ; parameter block filename ptr
BEQ.S XferFInfo ; skip it if it's zero
MOVE.L D0,A4
MOVE.B (A3),D0 ; name length
@1 MOVE.B (A3)+,(A4)+ ; name length, then name, byte by byte
SUBQ.B #1,D0
BCC.S @1
XferFInfo
BTST #HFSReq,HFSFlags ; Requesting full catalog information?
BNE.S XferCInfo ; If so, transfer it all
CMP.B #CDRFilRec,CDRType(A5) ; Otherwise, is this a file node?
BNE.S GFInfErr ; If not, that's trouble
LEA IOFlAttrib(A0),A4 ; info destination
MOVEQ #(IOFlMdDat+4-IOFlAttrib)/2-1,D0 ; number of words to copy - 1
LEA FilFlags(A5),A3 ; start of regular info to transfer
@1 MOVE.W (A3)+,(A4)+ ; move word by word
DBRA D0,@1
;
; Clear the directory flag for file information:
;
BCLR #ioDirFlg,ioFlAttrib(A0) ; 0 = file info returned
;
; Code shared by MFS entries (GetMFlInfo, GtMFlIBI):
;
CkFilStatus ANDI.B #$73,ioFlAttrib(A0) ;Clear out busy, DFBusy, and RFBusy flags <06Nov85>
CLR.W IORefnum(A0) ; Clear refnum in case file isn't open <27Oct85>
MOVE.L FilFLNum(A5),D2 ; Get file number from TFS cat. entry
BSR TFSVCBTst ; Are we dealing with a TFS volume? <01Oct85>
BEQ.S @0 ; If TFS, handle TFS catalog entries
MOVE.L FlFlNum(A5),D2 ; get the file number from MFS dir. entry
; scan through the FCBs and look for a match of file number and same volume
@0 BSR Gt1stMatch
BNE.S @10 ; If there's no match, we're set. <27Oct85>
@1 BTST #FCBRscBit,FCBMdRByt(A1,D1) ; Is this a resource file? <27Oct85>
BEQ.S @3 ; If not, set different flag <27Oct85>
BSET #2,ioFlAttrib(A0) ; Mark resource fork busy <27Oct85>
BRA.S @5 ; <27Oct85>
@3 BSET #3,ioFlAttrib(A0) ; Mark data fork busy <27Oct85>
@5 BSET #7,ioFlAttrib(A0) ; Mark file busy <27Oct85>
BNE.S @7 ; If already set, don't overwrite refNum <27Oct85>
MOVE.W D1,IORefnum(A0) ; note the refnum of fcb entry
; the file is opened, so we update the return information appropriately in case
; the file has been modified . . .
@7 LEA IOFlStBlk(A0),A3 ; info destination, regular fork
BSR UpDatFlNtry ; update info (shared with close)
BSR GtNxtMatch ; Look for next matching FCB <27Oct85>
BEQ.S @1 ; Continue if another FCB is found <27Oct85>
@10 MOVEQ #0,D0 ; no errors
BRA GFIExit
; Transfer all catalog information:
XferCInfo LEA IOFlAttrib(A0),A4 ; info destination
CMP.B #CDRFilRec,CDRType(A5) ; Is this a file node?
BNE.S @50 ; If not, it's probably a directory
MOVEQ #(ioFlxFndrInfo+16-IOFlAttrib)/2-1,D0 ; number of words to copy - 1 <24Sep86>
LEA FilFlags(A5),A3 ; start of regular info to transfer
@1 MOVE.W (A3)+,(A4)+ ; move word by word
DBRA D0,@1
MOVEQ #0,D0 ; Clear top word
MOVE.W FilClpSize(A5),D0 ; Pick up clump size in allocation blocks
MULU VCBAlBlkSiz+2(A2),D0; Convert to bytes
MOVE.L D0,ioFlClpSiz(A0) ; Return it to the user
MOVE.L D1,IOFlParID(A0) ; Return parent information
;
; Clear the directory flag for file information:
;
BCLR #ioDirFlg,ioFlAttrib(A0) ; 0 = file info returned
BRA CkFilStatus
@50 CMP.B #CDRDirRec,CDRType(A5) ; Is this a directory node?
BNE GFInfErr ; If not, there went our last chance
MOVE.W DirFlags(A5),IOFlAttrib(A0) ; Copy attribute bytes
MOVE.W DirVal(A5),IODrNmFls(A0) ; Copy dir. entry count
MOVE.L DirDirID(A5),IODrDirID(A0) ; Copy Directory ID
MOVE.L D1,IODrParID(A0) ; Return parent dir ID
MOVEM.L DirCrDat(A5),D0-D2 ; Pick up DTC, DTM, and DTB
MOVEM.L D0-D2,IODrCrDat(A0) ; And copy them into the user IOPB
MOVEM.L DirUsrInfo(A5),D0-D3 ; Pick up 16 bytes of user info
MOVEM.L D0-D3,IODrUsrWds(A0); Copy them into the parameter block
MOVEM.L DirFndrInfo(A5),D0-D3 ; Pick up 16 bytes of Finder info
MOVEM.L D0-D3,IODrFndrInfo(A0); Copy them into the parameter block
BCLR #7,IOFlAttrib(A0) ; Directories are never too busy for ya
; Set the directory flag for directory information:
BSET #ioDirFlg,ioFlAttrib(A0) ; 1 = directory info returned
@90 MOVEQ #0,D0 ; Indicate success
BRA GFIExit ; And leave.