; ; 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): ; ; 8/27/93 BH Removed . The flushing stuff is now in CmdDone. ; 8/3/93 BH Flushing critical volume info when changed for a volume in a ; manual-eject drive. ; 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 @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> 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> ; 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 '' must ; have led us to the directory descriptor for 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.