supermario/base/SuperMarioProj.1994-02-09/OS/HFS/MFSDIR2.a
2019-06-29 23:17:50 +08:00

285 lines
9.9 KiB
Plaintext

;
; File: MFSDIR2.a
;
; Contains: This file contains file-level routines which use filenames.
;
; Copyright: © 1982-1991 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <2> 9/12/91 JSM Add a header.
; <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…
; 9/24/86 BB Updated to use new MPW equates
; 10/20/85 LAK Flush control cache on exit of MFSDelete, MFSRename.
; 10/9/85 LAK One more bug fixed in MFSRename.
; 10/8/85 LAK Fixed bugs introduced in MFSRename use of A6 stack change.
; 10/1/85 LAK Adjusted for new use of cache. Rename now uses A6 stack. Delete
; trashes file blocks in cache.
; 9/5/85 LAK Don't allow Rename of locked files.
; 8/31/85 LAK Set VCB time after rename to signal Finder that something
; changed (don't dirty it since mod-date isn't so important).
; 3/10/85 PWD Created from FSDir2.Text; now contains only MFS-specific code.
; FileDelete and Rename trap entries are in TFSDir2.
; 8/29/83 LAK Changed ReName to update affected FCBs FCBFlPos (rename may
; cause a directory entry to migrate).
; 6/4/83 LAK No longer calls DtrmVol (this is done by FndFilNam) since case
; of write-protected diskette is a low-percentage hit. Uses
; CkFilMod subroutine to save code.
; 4/20/83 LAK Minor change to CkFileBusy.
; 2/8/83 LAK Fixed rename bug (A5 trash)
; 1/16/83 LAK Added latest changes; cosmetic and documentation updates.
; 1/16/83 LAK Modified RemovEntry for new directory format (no entry length);
; updated documentation.
; 12/14/82 LAK Removed undelete scheme.
; 12/10/82 LAK Broke out routine to search FCBs by filenum (share it with
; GetFileInfo).
; 12/9/82 LAK Redid for new file data structures.
;
;_______________________________________________________________________
;
; External Routines: MFSDelete,MFSReName
;
; Internal Routines: RemoveEntry
;
;_______________________________________________________________________
;_______________________________________________________________________
;
; Routine: MFSDelete
;
; (c) 1983 Apple Computer, Inc.
;
; Arguments: A0.L (input) -- pointer to I/O parameter block; uses:
; IOFileName,IOFileType
; D0.W (output) -- error code
; This call may be executed asynchronously.
; Calls: FSQueue,CkFileBusy,DAlBlks,RemovEntry,CmdDone
; Function: Delete a file from an MFS volume. The file is removed from
; the directory and its blocks are freed up (both resource and
; normal fork blocks are deallocated). The entry is zeroed and
; any following entries are moved down. All blocks associated
; with the file are marked free in the block map and the VCB
; info is marked dirty.
;
; Modification History:
; 09 Dec 82 LAK Redid for new file data structures.
; 10 Dec 82 LAK Broke out routine to search FCBs by filenum (share it
; with GetFileInfo).
; 14 Dec 82 LAK Removed undelete scheme.
; 16 Jan 83 LAK Modified RemovEntry for new directory format (no entry
; length); updated documentation.
; 04 Jun 83 LAK No longer calls DtrmVol (this is done by FndFilNam) since
; case of write-protected diskette is a low-percentage hit.
; Uses CkFilMod subroutine to save code.
;_______________________________________________________________________
MFSDelete
;
; Begin by checking if file is locked or busy:
BLANKS ON
STRING ASIS
MOVEQ #FLckdErr,D0 ; assume locked
BTST #FlWrtFlag,FlFlags(A5) ; well, is it?
BNE.S MFDelExit ; br if so
BSR CkFileBusy ; is the file busy?
BNE.S MFDelExit ; exit if so . . .
SUBQ.W #1,VCBNmFls(A2) ; one less file
BSR MarkVCB ; mark VCB info dirty
MOVE.W FlStBlk(A5),D3 ; get start block to D3
BSR DAlBlks ; deallocate the blocks
MOVE.W FlRStBlk(A5),D3 ; deallocate the resource blocks also
BSR DAlBlks
MOVE.L FlFlNum(A5),D0 ; save file number from MFS dir entry <01Oct85>
BSR.S RemovEntry ; remove entry from the directory, mark block dirty
JSR TrashFBlocks ; trash all file blocks (pass A2,D0) <01Oct85>
BSR MFSCtlFlush ; flush control cache if it's too full <20Oct85>
MOVEQ #0,D0 ; success
MFDelExit BRA CmdDone
GtEntryLen MOVEQ #0,D0
MOVE.B FlNam(A5),D0
ADD.W #FlNTLen+2,D0
BCLR #0,D0
RTS
; delete file pointed to by A5 in block at A1 by moving all following entries
; down and zeroing the rest of the block (shared with Rename)
RemovEntry MOVEM.L A0/A1/A5/D0,-(SP)
MOVE.L A1,A0 ; <01Oct85>
JSR MarkBlock ; mark this buffer dirty <01Oct85>
CLR.L VCBDirIndex(A2) ; invalidate our index,blk num pair
MOVE.L A5,A0 ; start of entry to delete
BSR.S GtEntryLen ; length of entry -> D0
ADD.L D0,A5 ; next entry
ADD.W #BufSiz,A1 ; point to end of buffer
@1 CMP.L A1,A5 ; check for end of buffer
BCC.S @2 ; br if done
MOVE.W (A5)+,(A0)+ ; move rest of entries down
BRA.S @1
@2 CLR.W (A0)+ ; leave rest of block zeroed
CMP.L A1,A0
BCS.S @2
MOVEM.L (SP)+,A0/A1/A5/D0
RTS
;_______________________________________________________________________
;
; Routine: ReName
; Arguments: A0 (input) -- pointer to parameter block:
; D0 (output) -- error code
; Calls: FSQueue,DtrmVol,FndFilNam,CVFlgs,RemovEntry,FndFilSpc,
; GtEntryLen,CmdDone
; Function: Rename a file or a volume. For files, the directory is
; first searched for the target name (to make sure we don't
; get two files with the same name). If not found, the directory
; is then searched for the real file (using the source name);
; the entry is copied onto the stack and removed from the directory
; block. FndFilSpc is used to find space for the changed entry.
;
; Also note that a file may not be renamed with the same name.
;
; Modification History:
; 09 Dec 82 LAK Changed to use a new rename algorithm; updated for new
; file system data structures.
; 16 Jan 83 LAK Updated for final data structures.
; 05 Jun 83 LAK Added change to allow rename of a file to itself (for case
; changes).
; 29 Aug 83 LAK Fixed bug: rename now updates FCBs for the renamed file (opened
; files may be renamed) to point to correct directory block.
;
; Test: no more room in directory case . . .
; renaming a volume
; renaming both file and volume with 0-length name.
;_______________________________________________________________________
MFSReName:
MOVE.L A0,-(SP) ; preserve parameter block pointer
MOVE.W D2,D0 ; old name length
MOVE.L A4,A0 ; old name ptr
MOVEM.L FSTemp8,D2/A4 ; get back new name ptr and length
SWAP D0
MOVE.W D2,D0 ; new name length
MOVE.L A4,A1 ; new name ptr
_CmpString ; see if it's a case of the same name
MOVE.L (SP)+,A0
BEQ.S @2 ; br if so (skip the conflict check)
BSR FndFN2 ; look for the dest name in directory
BNE.S @1 ; (uses src volume)
MOVEQ #DupFNErr,D0 ; duplicate file name if found
@1 CMP #FNFErr,D0 ; file should not have been found
BNE.S MRNmExit ; also exit for ext fs, vol offline errs
@2 BSR FndFilName ; search directory for the source file
BNE.S MRNmExit ; if not around, bummers
MOVEQ #FLckdErr,D0 ; assume locked <05Sep85>
BTST #FlWrtFlag,FlFlags(A5) ; well, is it? <05Sep85>
BNE.S MRNmExit ; exit if so <05Sep85>
; At this point, A5 points to the file entry, and A1 points to the start of the
; buffer the directory block is in. We save the old entry on the A6 stack.
SavOldNtry MOVE.L A6,A4 ; save our stack pointer <01Oct85>
MOVE.L A5,A3 ; copy pointer to entry
BSR.S GtEntryLen ; entry length -> D0
@1 MOVE.W -2(A3,D0),-(A6) ; move it onto stack, backwards <01Oct85>
SUBQ #2,D0
BGT.S @1
; now reclaim the space for the old entry and mark the block dirty
BSR.S RemovEntry
MOVE.L FSTemp8,D2 ; get back dest name length <08Oct85>
BSR FndFilSpc ; go find us space <01Oct85>
BNE.S NoSpace ; br if none <08Oct85>
; ok, we have the space, so move in the new entry:
; A2.L = VCB ptr
; D2.W = new dir entry name length
; D5.W = entry total length
; A4.L = old stack pointer
; A5.L = pointer to space to put entry
MOVE.L A5,A3 ; save pointer to entry for AdjFlPos <09Oct85>
MOVEQ #(FlNtLen/2)-1,D0 ; move this much of the old entry
@3 MOVE.W (A6)+,(A5)+ ; move word by word <01Oct85>
DBRA D0,@3
MOVE.L A4,A6 ; get our old stack pointer back <01Oct85>
MOVEM.L FSTemp8,D2/A4 ; retrieve dest name ptr and length
MOVE.B D2,(A5)+ ; name length
@4 MOVE.B (A4)+,(A5)+ ; move byte by byte, including len byte
SUBQ.W #1,D2
BGT.S @4
BSR.S AdjFlPos ; adjust file position for any FCBs
BSR MarkVCBTime ; change the time in VCB to signal Finder <31Aug85>
BSR MFSCtlFlush ; flush control cache if it's too full <20Oct85>
MOVEQ #0,D0 ; no errors
MRNmExit BRA CmdDone
; the directory didn't have enough space, so at least try to get back to
; where we started . . .
NoSpace MOVE.B FlNam(A6),D2 ; get back src name length <08Oct85>
BSR FndFilSpc ; we should be able to get back at least <01Oct85>
BEQ.S @1 ;
MOVE.L A4,A6 ; get our old stack pointer back <01Oct85>
MOVEQ #fsRnErr,D0 ; some days are like this <24Sep86>
BRA.S MRNmExit
@1 MOVE.L A5,A3 ; save pointer to entry for AdjFlPos <09Oct85>
@2 MOVE.W (A6)+,(A5)+ ; move word by word <01Oct85>
CMP.L A6,A4 ; get back to where we started <01Oct85>
BNE.S @2
BSR.S AdjFlPos
MOVEQ #DirFulErr,D0 ; directory was too full
BRA.S MRNmExit ; so exit . . .
AdjFlPos MOVE.L FlFlNum(A3),D2 ; file number of this file <09Oct85>
MOVE.W CurDB,D0 ; get block number in D0 <01Oct85>
BSR Gt1stMatch ; update any matching files
BNE.S @2 ; exit if none
@1 MOVE.W D0,FCBFlPos(A1,D1) ; update file block
BSR GtNxtMatch
BEQ.S @1
@2 RTS