mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +00:00
4325cdcc78
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.
1122 lines
48 KiB
Plaintext
1122 lines
48 KiB
Plaintext
;
|
|
; File: TFSRFN2.a
|
|
;
|
|
; Contains: This file contains routines which operate on open files using
|
|
; refnums.
|
|
;
|
|
; Copyright: © 1982-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM7> 8/27/93 BH Removed <SM6>. The flushing stuff is now in CmdDone.
|
|
; <SM6> 8/3/93 BH Flushing critical volume info when changed for a volume in a
|
|
; manual-eject drive.
|
|
; <SM5> 5/20/93 kc Roll in R58 change from CubeE
|
|
; <R58> 6/22/92 csd #100889,1032495 <gbm>: Turned ClosePatch off.
|
|
; <SM4> 10/22/92 CSS Change some branch short instructions to branches.
|
|
; <SM3> 8/12/92 PN Radar #1036025. Clear the dirty bit of the FCBMdRByt when doing
|
|
; PBFlushFile call
|
|
; <SM2> 5/21/92 kc Append "Trap" to the names of GetEOFTrap and SetEOFTrap to avoid
|
|
; name conflict with the glue.
|
|
; <SM1> 4/1/92 kc Roll in DontTruncateMultiForks ComeFromPatchProc.
|
|
; Roll in ClosePatch from FileMgrPatches.a
|
|
; ¥ Pre-SuperMario comments follow ¥
|
|
; <2> 9/12/91 JSM Add a header.
|
|
; <1.3> 4/13/89 DNF Vectored FileClose. When patching, watch out for other HFS code
|
|
; which joins (jumps to) FileClose at FClose
|
|
; <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É
|
|
; 2/19/87 BB Vectored FClose.
|
|
; 2/3/87 BB Replaced use of "FCBEntLen" equate with the use of low memory
|
|
; variable "FSFCBLen".
|
|
; 12/12/86 BB Removed use of FCBClmpSize in FClose
|
|
; 10/27/86 BB Vectored TstMod routine.
|
|
; 9/24/86 BB Updated to use new MPW equates.
|
|
; 1/14/86 LAK Added ROM75Fix patches: set up A2 in FndFCB for non-indexed
|
|
; GetFCBInfo; pass appropriate flags to AllocTFS for FileAlloc;
|
|
; changed FClose and SetEOF calls to pass D2 options to
|
|
; TruncateFile; TstMod1 entry added and used by FClose which may
|
|
; not have a valid A0.
|
|
; 11/6/85 PWD Changed GetFCBInfo to skip volume control files when indexing.
|
|
; 11/1/85 PWD Fixed GetFCBInfo index FCB search (clobbered index if VRefNum
|
|
; specified)
|
|
; 10/29/85 LAK Vectored RfnCall, AdjEOF.
|
|
; 10/28/85 PWD Changed SetEOF to leave clump size rounding to TruncateFile
|
|
; 10/27/85 PWD Gutted LockRng and UnlockRng routines: leave code to check for
|
|
; ext. FS etc. but don't do anything for single-user local Mac
|
|
; systems.
|
|
; 10/21/85 LAK Flush file buffers more frequently (even for data forks of
|
|
; files) and close files even on most error conditions.
|
|
; 10/20/85 LAK Added flush of control cache for MFS volumes at FClose.
|
|
; 10/16/85 PWD Added LockRng and UnlockRng routines.
|
|
; 10/13/85 PWD Rewrote FndFCB to reduce code size (at some minor cost in speed)
|
|
; Changed SetEOF to interpret H-Bit to mean SetPEOF (vs. SetLEOF).
|
|
; 10/1/85 LAK FileAlloc no longer calls MFSFAlloc (code is shared since it was
|
|
; the same). AllocContig (Allocate with H-bit set) is finally
|
|
; supported. THIS STILL NEEDS SOME WORK. Moved MFSClose code here
|
|
; to share more code (flush of cache, clearing FCB space).
|
|
; Subroutined out CkFileRfn for FndFCB and RfNCall to share. All
|
|
; internal errors are now converted at CmdDone.
|
|
; 9/25/85 PWD Backed out of previous Close truncation change: truncate to PEOF
|
|
; to make sure space _Allocated is retained.
|
|
; 9/22/85 PWD Changed to truncate to LEOF instead of PEOF on Close.
|
|
; 9/21/85 LAK Call TrashBlocks instead of FlushCache in SetEOF shorten path.
|
|
; 9/6/85 LAK Finished removal of OwnBuf support (in SetEOF shorten path).
|
|
; 8/29/85 BB Added support for contiguous allocation (TFS FileAlloc).
|
|
; 8/29/85 LAK Don't flush MDB on file flush . . . (whole lotta flushin' going
|
|
; on). Also removed support for TFS OwnBuf.
|
|
; 8/22/85 PWD Changed to honor file-specific clump sizes
|
|
; 6/20/85 PWD Changed to use system CNode equates
|
|
; 6/19/85 PWD Changed non-hardware internal errors to FSDSIntErr.
|
|
; 6/4/85 PWD Removed SetFCBInfo entry point
|
|
; 5/28/85 PWD Added _SetFCBInfo
|
|
; 5/21/85 PWD Added _GetFCBInfo
|
|
; 5/6/85 PWD Changed FClose to flush FCB extent record to catalog.
|
|
; 4/25/85 PWD Changed FClose to truncate files open for write to their PEOF on
|
|
; close.
|
|
; 4/25/85 PWD Changed to convert all internal errors to IOErr.
|
|
; 4/4/85 PWD Expanded FClose to flush/close B*-Tree files
|
|
; 8/3/84 GSS Patched SetEOF to include SetEOFix patch from MSFileFix
|
|
; 8/2/84 GSS Put patch in RfnCall from MSFileFix (ReqstVol fix)
|
|
; 7/5/84 GSS Put FileAlloc patches in line from MSFileFix
|
|
; 8/31/83 LAK Subroutined part of FClose to share with GetFileInfo fix.
|
|
; 8/30/83 LAK Fixed bug in ADJEOF (A1) -> (A0)
|
|
; 3/6/83 LAK Fixed bug in SetEOF with IOLEOF = 0 (now deallocates the disk
|
|
; blocks . . .)
|
|
; 1/17/83 LAK Last pass changes.
|
|
; 12/21/82 LAK Changed to share code with fileclose . . .
|
|
; 12/8/82 LAK Reworked all files for new file system data structures. Changed
|
|
; refnum validity check in RFnCall.
|
|
; 12/7/82 LAK Changed to support mutiple VCB queue; only flushes files -
|
|
; FlushVol is used to flush a volume.
|
|
;
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; External Routines: FileClose,FlushFile,SetEOF,GetEOF,GetFCBInfo
|
|
; LockRng,UnlockRng,FileAlloc
|
|
;
|
|
; Internal Routines: RfNCall,AdjEOF,TstMod
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FlushFile
|
|
; Arguments: A0.L (input) -- I/O parameter block: uses
|
|
; IORefnum: file to be flushed
|
|
; D0.W (output) -- error code
|
|
; Calls: RfNCall,FClose
|
|
;
|
|
; Function: Flushes the buffers associated with a file and writes any
|
|
; changed FCB info out to the disk directory.
|
|
;
|
|
; Modification History:
|
|
; 07 Dec 82 LAK Changed to support mutiple VCB queue; only flushes files -
|
|
; FlushVol is used to flush a volume.
|
|
; 21 Dec 82 LAK Changed to share code with fileclose . . .
|
|
;
|
|
; - the volume block map is not flushed; should it be?
|
|
;_______________________________________________________________________
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
FlushFile BSR FSQueue
|
|
ST FlushOnly ; only flush
|
|
BRA.S FlCls1
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FileClose
|
|
; (c) 1983 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IORefNum = refnum of file to close
|
|
; D0.W (output) -- 0 if file closed ok, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls: FSQueue,RFnCall,FClose,CmdDone
|
|
; Function: Remove a file from active duty.
|
|
;
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 02 Dec 82 LAK A3 and A5 set up by FClose, so removed a line.
|
|
; Uses DisposBuf to get rid of any allocated buffer.
|
|
; 20 Dec 82 LAK Modified for new file system data structures; no longer
|
|
; returns buffer memory (buffer supplied by caller at open time);
|
|
; checks for resource/regular part of a file.
|
|
; 06 Jun 83 LAK Made Flush, Close ok for offline files.
|
|
;
|
|
; Sharable routines: routine to search a directory block for a file number.
|
|
;_______________________________________________________________________
|
|
|
|
FileClose:
|
|
MOVE.L jFileClose,-(SP) ; jumptable entry for vFileClose <dnf v1.3>
|
|
RTS ; go there
|
|
vFileClose: ; 'vectored' FileClose routine
|
|
|
|
; From ClosePatch in FileMgrPatches.a
|
|
;
|
|
; Function: Prevent a file _Close from occuring on a file that was opened by kSystemProcess
|
|
; unless we're currently running kSystemProcess. This keeps random people (apps with
|
|
; housekeeping code that closes lots of files, for example) from closing system-like
|
|
; files out from under us.
|
|
|
|
ClosePatchRegs reg a0-a2/d0-d1
|
|
|
|
movem.l ClosePatchRegs,-(sp) ; save regs we use
|
|
movea.l sp,a2 ; for safe, quick stack pointer restore
|
|
|
|
; *** NOTE: THIS PATCH IS DISABLED *** ; <R58>
|
|
; This patch was broken in System 7, and fixed with change <53>. The fix ; <R58>
|
|
; causes some third-party applications (QuicKeys, Retrospect Remote) to stop ; <R58>
|
|
; working because they are unable to close files. For Cube-E, weÕll re-break this ; <R58>
|
|
; patch and revisit the entire issue later. ; <R58>
|
|
; <R58>
|
|
bra.s DoClosePop ; <58> Disable this patch ; <R58>
|
|
|
|
; check the refnum for validity. and locate the parallel FCB array element
|
|
move.w ioRefNum(a0),d0 ; get refnum being closed
|
|
bsr RefNumCheck ; is it legit?
|
|
bne.s DoClosePop ; if not, let the real trap deal with it
|
|
move.w ioRefNum(a0),d0 ; get refnum being closed
|
|
bsr ParallelFCBFromRefnum ; a1 = address of parallel FCB element
|
|
|
|
; check whether we have tagged the file -- this makes sure that we can even call the
|
|
; Process Mgr (since files are tagged only when the Process Mgr is available), but is
|
|
; cheaper than ProcessMgrExists
|
|
tst.l xFCBPid2(a1) ; is low long initialized?
|
|
bne.s @NeedToCheck ; jump if so, we need to make the trap calls
|
|
tst.l xFCBPid1(a1) ; is high long initialized?
|
|
beq.s DoClosePop ; both are uninitialized, OK to close!
|
|
|
|
; the quicker of the two checks is whether file opened by kSystemProcess, do it first
|
|
@NeedToCheck
|
|
pea kSystemProcess ; push low long of PSN
|
|
|
|
clr.l -(sp) ; push high long of PSN
|
|
clr.l -(sp) ; allocate storage for boolean and result
|
|
pea 4(sp) ; push address of kSystemProcess
|
|
pea xFCBPid1(a1) ; push address of PSN from parallel FCB
|
|
pea 10(sp) ; push address of Boolean
|
|
_SameProcess ; compare FCB PSN to kSystemProcess
|
|
addq.l #2,sp ; dump OSErr (Boolean OK on error)
|
|
tst.w (sp) ; check Boolean (still false if error)
|
|
beq.s DoClosePop ; jump if FCB not opened by kSystemProcess
|
|
|
|
; OK, file was opened by kSystemProcess, see whether _Close caller is also kSystemProcess
|
|
clr.w (sp) ; set Boolean to "false", for easier check later
|
|
suba.l #10,sp ; allocate storage for PSN (8 bytes) and result
|
|
pea 2(sp) ; push address of PSN storage
|
|
_GetSystemClientProcess ; get party responsible for this _Close call
|
|
pea 2(sp) ; push address of client PSN
|
|
pea 16(sp) ; push address of kSystemProcess
|
|
pea 18(sp) ; push address of Boolean
|
|
_SameProcess ; is current client same as kSystemProcess?
|
|
tst.w 10(sp) ; check boolean
|
|
beq.s DontClosePop ; if "false", caller is not kSystemProcess
|
|
|
|
; file not opened by kSystemProcess, or closer is also kSystemProcess
|
|
DoClosePop
|
|
movea.l a2,sp ; restore stack
|
|
movem.l (sp)+,ClosePatchRegs ; restore regs we used
|
|
|
|
BSR FSQueue ; wait until ready...
|
|
CLR.B FlushOnly ; flush and close the file
|
|
|
|
FlCls1 BSR RFnCall ; detect if file open, get FCB pointer
|
|
BEQ.S @1 ; br if ok
|
|
CMP.W #VolOffLinErr,D0 ; was it just off-line? exit for ext fs here
|
|
BNE.S ClsExit ; (close is ok for offline files cause
|
|
; they've been flushed)
|
|
@1 BSR.S FClose ; actually do flush and close now
|
|
|
|
ClsExit BRA CmdDone ; that's all folks.
|
|
|
|
; file was opened by kSystemProcess, but is being closed by someone else. Just say no!
|
|
DontClosePop
|
|
movea.l a2,sp ; restore stack
|
|
movem.l (sp)+,ClosePatchRegs ; restore regs we used
|
|
moveq.l #permErr,d0 ; set error code
|
|
move.w d0,ioResult(a0) ; agree in the iopb
|
|
rts ; return to caller
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FClose
|
|
;
|
|
; Arguments: Enter with (A1,D1) pointing at the FCB.
|
|
; FlushOnly (input) -- low memory flag: if 1, then flush only,
|
|
; do not close . . .
|
|
; All registers except D0 preserved.
|
|
; Calls: MyWriteBk,MyReadBk
|
|
; Called by: FileClose,FlushVolume,FlushFile
|
|
; Function: Called when file system wants to close or flush a file.
|
|
; Returns to one level above caller during execution.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 02-Dec-82 LAK Set up A2,A3 and A5 early to save bytes; reworked format.
|
|
; Uses Time global for modification date.
|
|
; 20-Dec-82 LAK Modified for latest file system changes . . . no longer
|
|
; writes directory block out, but marks it dirty . . .
|
|
; 21-Dec-82 LAK Uses low memory variable FlushOnly for flush-only flag (if
|
|
; zero, then close file, too)
|
|
; 17-Jan-83 LAK Modified for new directory entry data structure (no entry
|
|
; length byte, physical length in bytes)
|
|
; 4-Apr-85 PWD Modfied to close/flush B*-Tree file for TFS
|
|
; 25-Apr-85 PWD Changed FClose to truncate files to their PEOF on Close when
|
|
; open for write.
|
|
; 16-May-85 PWD Added options to FlushCache call, added code to write a copy
|
|
; of the file's catalog entry into the resource fork.
|
|
; 22-Aug-85 PWD Added code to round to file-specific clump size on truncate.
|
|
; 22-Aug-85 PWD Added code to flush out VCB for volume on _FlushFile.
|
|
; 22-Sep-85 PWD Changed to truncate to LEOF instead of PEOF on Close.
|
|
; 25-Sep-85 PWD Backed out of previous Close truncation change: truncate to
|
|
; PEOF to make sure space _Allocated is retained.
|
|
; <28Oct85> PWD Changed to save all registers except D0 across call
|
|
; <21May86> BB Modified to only call BTClose and BTFlush for system files.
|
|
; Note, this fix helps our file server friends but prohibits
|
|
; the use of BTClose and BTFlush for other user BTree files.
|
|
; ROM75FIX patch #43, Change Log # C8
|
|
; <19Aug87> BB/JB (C867) Fixed FClose problem which was not releasing BTCB's
|
|
; for eject, offline, and unmount.
|
|
;_______________________________________________________________________
|
|
|
|
FClose:
|
|
MOVE.L jFClose,-(SP) ; jump table entry for vFClose <19Feb87>
|
|
RTS ; go there <19Feb87>
|
|
vFClose ; 'vectored' FClose routine <19Feb87>
|
|
MOVE.L (SP)+,-(A6) ; save caller's addr <01Oct85>
|
|
MOVEM.L A0-A5/D1-D3,-(A6) ; Store scratch registers <28Oct85>
|
|
BSR TFSVCBTst ; Is this a TFS volume? <01Oct85>
|
|
BNE MFSClose ; Nope
|
|
|
|
TST.L FCBBTCBPtr(A1,D1) ; BTCB associated with this open file?
|
|
BEQ.S @3 ; No - just an ordinary file
|
|
CMPI.L #FSUsrCNID,FCBFlNm(A1,D1) ; a user BTree file? <21May86>
|
|
BHS.S @3 ; yes, don't BTFlush or BTClose it <19Aug87>
|
|
MOVE.W D1,D0 ; Copy RefNum
|
|
TST.B FlushOnly ; Just flushing?
|
|
BNE.S @1 ; Yes - don't close the B*-Tree file
|
|
JSR BTClose ; Flush & Close the B*-Tree file
|
|
BRA.S @2 ;
|
|
@1 JSR BTFlush ; Just flush B*-Tree information
|
|
@2 BNE FClsDn ; Bad time for errors (from CMGetCN)
|
|
|
|
@3 MOVEQ #0,D0 ; pass D0=0 to FlDone <21Oct85>
|
|
TST.W VCBDrvNum(A2) ; Volume offline?
|
|
BEQ FlDone ; If EQ, it is
|
|
|
|
CMP.L #FSUsrCNID,FCBFlNm(A1,D1) ; Special volume control file?
|
|
BLO FlDone ; If so, there's no catalog entry <29Aug85>
|
|
|
|
BCLR #FCBModBit,FCBMdRByt(A1,D1) ; in case the file is unmodified,
|
|
BEQ FlFilBuf ; we need not update the file catalog <21Oct85>
|
|
|
|
ResetAEOF ;<14Jan86>;TST.B FlushOnly ; Just flushing?
|
|
;<14Jan86>;BNE.S UpdFlCat ; If so, don't adjust the EOF
|
|
BSR TstMod1 ; Can we actually modify the file? <14Jan86>
|
|
; (may have been ejected and locked) <14Jan86>
|
|
BNE.S updFlCat ; If not, just update the catalog entry
|
|
|
|
MOVE.L FCBPLen(A1,D1),D3 ; New end of file <25Sep85>
|
|
; BTST #FCBOwnClp,FCBMdRByt(A1,D1) ; Clump size set for file? <12Dec86>
|
|
; BEQ.S @1 ; If not, truncate to this position <12Dec86>
|
|
|
|
; Round to next higher clump size:
|
|
|
|
; MOVEM.L D0-D1,-(SP) ; Save scratch regs. across call <12Dec86>
|
|
; MOVE.L D3,D0 ; Get new EOF <12Dec86>
|
|
; MOVE.L FCBClmpSize(A1,D1),D1 ; Get clump size for file <12Dec86>
|
|
; BSR RoundAlloc ; Compute new EOF, rounded to clump size <12Dec86>
|
|
; MOVE.L VCBAlBlkSiz(A2),D1 ; Pick up vol's aloc. block size <12Dec86>
|
|
; MULU D1,D0 ; Compute new EOF in bytes <12Dec86>
|
|
; MOVE.L D0,D3 ; Stash it for real-life use <12Dec86>
|
|
; MOVEM.L (SP)+,D0-D1 ; Restore scratch registers <12Dec86>
|
|
|
|
@1 MOVEQ #0,D2 ; Truncate to alloc block <14Jan86>
|
|
; from DontTruncateMultiForks <SM1>.start
|
|
|
|
@Regs reg d1-d4 ; <44>
|
|
; Look for other paths to the same fork as the one being closed.
|
|
MOVEM.L @Regs,-(SP) ; save input parameters <11Dec90 #17>
|
|
MOVE.W D1,D3 ; D3.W = our FCB <11Dec90 #17>
|
|
MOVE.L FCBFlNm(A1,D3.W),D2 ; D2.L = our file number <11Dec90 #17>
|
|
move.b fcbMdRByt(a1,d3.w),d4 ; d4.b = our fork's misc info <44>
|
|
|
|
BSR Gt1stFCB ; get (A1,D1) pointing to first FCB <11Dec90 #17>
|
|
@2 CMP.W D1,D3 ; same FCB? <11Dec90 #17>
|
|
BEQ.S @3 ; skip ourself if it is <11Dec90 #17>
|
|
CMP.L FCBFlNm(A1,D1),D2 ; file numbers match? <11Dec90 #17>
|
|
BNE.S @3 ; no <11Dec90 #17>
|
|
CMP.L FCBVPtr(A1,D1),A2 ; on the same volume? <11Dec90 #17>
|
|
bne.s @3 ; no <44>
|
|
move.b fcbMdRByt(a1,d1.w),d0 ; grab this forkÕs kind <44>
|
|
eor.b d4,d0 ; see how it compares against ours <44>
|
|
btst.l #fcbRscBit,d0 ; are we the same? <44>
|
|
beq.s @7 ; if so, then there's another open path <44>
|
|
@3 BSR GtNxtFCB ; get next one until we run out <11Dec90 #17>
|
|
BCS.S @2 ; continue if more <11Dec90 #17>
|
|
|
|
; No second open path found, so do the truncate
|
|
MOVEM.L (SP)+,@Regs ; restore regs and <11Dec90 #17>
|
|
JSR TruncateFile ; Truncate to this position
|
|
BNE FlFilBErr ; Bad time for errors (from CMGetCN) <21Oct85>
|
|
BCLR #FCBModBit,FCBMdRByt(A1,D1) ; mark the FCB clean again in <PN>
|
|
BRA.S updFLCat
|
|
|
|
; A second path was found, so skip the truncation
|
|
|
|
@7 MOVEM.L (SP)+,@Regs ; we did nothing, but quite successfully <SM1>.end
|
|
BCLR #FCBModBit,FCBMdRByt(A1,D1) ; mark the FCB clean again in <14Jan86>
|
|
; case marked dirty by TruncateFile <14Jan86>
|
|
; Now retrieve the file's catalog entry, and update the information there:
|
|
|
|
updFlCat MOVE.L A1,-(A6) ; Save A1 across CMGetCN call
|
|
MOVE.L FCBDirID(A1,D1),D0 ; Set up parent's DirID
|
|
LEA FCBCName(A1,D1),A0 ; Point to file's CName
|
|
MOVEQ #0,D2 ; No file hint
|
|
JSR CMGetCN ; Look up the file entry in the catalog
|
|
MOVEA.L A1,A5 ; Stash file record pointer (same CC)
|
|
MOVEA.L (A6)+,A1 ; Restore FCB array pointer (same CC)
|
|
BNE FlFilBErr ; Bad time for errors (from CMGetCN) <21Oct85>
|
|
|
|
MOVEM.L A0-A1,-(SP) ; Save A0,A1 across _BlockMove
|
|
LEA FCBExtRec(A1,D1),A0 ; Point to extent record in FCB
|
|
LEA filExtRec(A5),A3 ; Point to data fork extent record
|
|
BTST #FCBFlgRBit,FCBMdRByt(A1,D1) ; Resource fork?
|
|
BEQ.S @1 ; If clear, this is a data fork FCB <29Aug85>
|
|
LEA filRExtRec(A5),A3 ; Point to resource fork extent record
|
|
@1 MOVEA.L A3,A1 ; Set dest. for _BlockMove
|
|
MOVEQ #lenXDR,D0 ; Length of extent record to copy
|
|
_BlockMove ; Copy it into the catalog
|
|
MOVEM.L (SP)+,A0-A1 ; Restore original A0,A1
|
|
|
|
LEA filStBlk(A5),A3 ; Update destination for UpDatFlNtry
|
|
BSR UpDatFlNtry ; Update the catalog
|
|
MOVE.L Time,filMdDat(A5) ; Set date/time modified
|
|
JSR CMUpdateCN ; Write out the modified catalog entry
|
|
BNE FlFilBErr ; Bad time for errors (from CMGetCN) <SM4> CSS
|
|
|
|
BTST #FCBFlgRBit,FCBMdRByt(A1,D1) ; Resource fork?
|
|
BEQ FlFilBuf ; Br if not <21Oct85> <SM4> CSS
|
|
CMP.L #128,FCBEOF(A1,D1) ; Room for a catalog entry copy?
|
|
BCS FlFilBuf ; If not, forget it <21Oct85> <SM4> CSS
|
|
|
|
MOVEM.L A1/D1,-(A6) ; Save FCB pointer across call
|
|
MOVE.L A0,A3 ; Save Key pointer
|
|
MOVEA.L VCBBufAdr(A2),A1 ; Point to volume cache
|
|
MOVE.W D1,D0 ; Set up file refNum
|
|
MOVEQ #0,D1 ; No options on GetBlock
|
|
MOVEQ #0,D2 ; First block of resource fork
|
|
JSR GetBlock ; Read it into the cache
|
|
BNE.S @2 ; Br on errors <21Oct85>
|
|
|
|
MOVE.L A0,-(SP) ; Save block pointer
|
|
LEA 48(A0),A1 ; Point into the block to write catalog entry
|
|
LEA ckrCName(A3),A0 ; Point to CNode name there
|
|
MOVEQ #(lenCKR-4-2),D0 ; Length of key - dirID - length byte+filler
|
|
_BlockMove ;
|
|
MOVEQ #(lenCKR-4-2),D0 ; Same length again
|
|
ADDA.L D0,A1 ; Update destination pointer
|
|
|
|
LEA filFlags(A5),A0 ; Source: catalog entry
|
|
MOVEQ #(filUsrWds+16-filFlags),D0 ; length to copy
|
|
_BlockMove ;
|
|
MOVEQ #(filUsrWds+16-filFlags),D0 ; length to advance pointer by
|
|
ADDA.L D0,A1 ; Update destination pointer
|
|
|
|
LEA filFndrInfo(A5),A0 ; Point to additional finder info
|
|
MOVEQ #16,D0 ; Length of finder info
|
|
_BlockMove ;
|
|
MOVEQ #16,D0 ; Distance to advance pointer
|
|
ADDA.L D0,A1 ; Advance the pointer
|
|
|
|
MOVE.L filCrDat(A5),(A1)+ ; Copy creation date
|
|
MOVE.L filLgLen(A5),(A1)+ ; Copy data fork's logical length
|
|
MOVE.L filRLgLen(A5),(A1)+ ; Copy resource fork's logical length
|
|
|
|
; Release the block again:
|
|
|
|
MOVEA.L (SP)+,A0 ; Restore block pointer
|
|
MOVEA.L VCBBufAdr(A2),A1 ; Cache Queue Header
|
|
MOVEQ #kRBDirty,D1 ; Block is dirty <01Oct85>
|
|
JSR RelBlock ; Release the block
|
|
|
|
@2 MOVEM.L (A6)+,A1/D1 ; Restore FCB pointer <21Oct85>
|
|
|
|
; Whether or not the file has been modified, flush it out so that no cache blocks are
|
|
; left around with invalid file refnums (future cache schemes may choose to ignore the
|
|
; trash option, but these may still want some indication of open/close for priority).
|
|
;
|
|
; MFS code rejoins us here . . .
|
|
|
|
FlFilBuf: MOVEQ #0,D0 ; Report success . . . <21Oct85>
|
|
|
|
; This entrypoint is used when an error has been encountered earlier. We flush
|
|
; Cache blocks for this file and still delete the FCB entry, but an error will
|
|
; be reported.
|
|
|
|
FlFilBErr: MOVEM.L A1/D0-D1,-(A6) ; Save regs across FlushCache <21Oct85>
|
|
MOVE.W D1,D0 ; set up to make a flushcache for the file
|
|
MOVEQ #0,D1 ; Clear options on FlushCache
|
|
TST.B FlushOnly ; Just flushing?
|
|
BNE.S @1 ; If so, keep cache blocks after flush
|
|
MOVEQ #kFCTrash,D1 ; Set flag to discard flushed cache blocks <01Oct85>
|
|
@1 MOVEA.L VCBBufAdr(A2),A1 ; Point to volume buffer
|
|
JSR FlushCache
|
|
|
|
BSR TFSVCBTst ; TFS vol <20Oct85>
|
|
BEQ.S @2 ; br if so <20Oct85>
|
|
BSR MFSCtlFlush ; flush control buffer for MFS <20Oct85>
|
|
|
|
@2 MOVEM.L (A6)+,A1/D0-D1 ; Restore FCB pointer, result code <21Oct85>
|
|
|
|
; D0 = result code here. We remove the entry if we are closing the file . . .
|
|
|
|
FlDone TST.B FlushOnly ; Check if we're just flushing
|
|
BNE.S fClsDn ; If so, we're all set <21Oct85>
|
|
|
|
LEA 0(A1,D1),A3 ; Point to the FCB entry
|
|
MOVEQ #0,D2 ; <03Feb87>
|
|
MOVE.W FSFCBLen,D2 ; (FCB length / 2) - 1 <03Feb87>
|
|
LSR.W #1,D2 ; <03Feb87>
|
|
SUBQ.W #1,D2 ; = number of words to clear <03Feb87>
|
|
|
|
@1 CLR.W (A3)+ ; First longword cleared marks FCB free
|
|
DBRA D2,@1 ; But let's go all out <21Oct85>
|
|
|
|
; D0 = result code here. We simply exit.
|
|
|
|
fClsDn MOVEM.L (A6)+,A0-A5/D1-D3 ; Restore scratch registers <28Oct85>
|
|
MOVE.L (A6)+,-(SP) ; go to caller with CCR reflecting D0
|
|
TST.W D0
|
|
RTS
|
|
|
|
MFSClose:
|
|
BCLR #FCBModBit,FCBMdRByt(A1,D1) ; in case the file is unmodified,
|
|
BEQ.S FlFilBuf ; we need not update the file catalog <21Oct85>
|
|
|
|
MOVE.W FCBFlPos(A1,D1),D3 ; file block number put here at open
|
|
BSR MFSDirRead ; read in the block to the volume's buffer <01Oct85>
|
|
BNE.S FlFilBErr ; this could be a real problem for user. <21Oct85>
|
|
|
|
; now find file entry within this dir block.
|
|
|
|
MOVEQ #0,D0 ; init index (should be zero anyway)
|
|
MOVE.L FCBFlNm(A1,D1.W),D3 ; look for file with same file num
|
|
|
|
@1 CMP.L FlFlNum(A5,D0.W),D3 ; this file?
|
|
BEQ.S @2 ; yes, got it to close it.
|
|
BSR GtNxEntry
|
|
BCS.S @1 ;
|
|
; if file disappears...
|
|
MOVEQ #FNFErr,D0
|
|
BRA.S FlFilBErr ; exit if we can't find it . . . <21Oct85>
|
|
|
|
@2 LEA FlStBlk(A5,D0),A3 ; destination for regular fork
|
|
BSR.S UpDatFlNtry ; code saving routine (trashes A3,D3)
|
|
|
|
MOVE.L Time,FlMdDat(A5,D0) ; use time global var for mod time
|
|
JSR MarkA5Block ; mark the block dirtied <01Oct85>
|
|
|
|
BRA.S FlFilBuf ; rejoin TFS code to flush cache for <01Oct85>
|
|
; this file.
|
|
|
|
; code sharing routine also used by GetFileInfo . . . A3 is reg fork destination
|
|
|
|
UpDatFlNtry
|
|
MOVE.L A4,-(SP) ; preserve A4
|
|
LEA FCBMdRByt(A1,D1),A4
|
|
MOVE.W (A4)+,D3 ; FCBMdRByt
|
|
LSL.W #7,D3 ; get FCBRscBit into carry
|
|
BCC.S @1 ; br if not the resource fork
|
|
ADD #10,A3 ; destination for rsrc fork is 10 later
|
|
|
|
@1 MOVE.W (A4)+,(A3)+ ; file start block (FCBSBlk)
|
|
MOVE.L (A4)+,(A3)+ ; file logical length (FCBEOF)
|
|
MOVE.L (A4)+,(A3)+ ; file physical length (FCBPLen)
|
|
MOVE.L (SP)+,A4 ; restore A4
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetEOF
|
|
; (c) 1983 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IORefNum,IOLEOF
|
|
; D0.W (output) -- 0 if file open, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls: FSQueue,RfNCall,CmdDone
|
|
; Function: Get logical length information for an opened file.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 21 Dec 82 LAK Modified for new file system data structures.
|
|
; 17 Jan 83 LAK No longer returns physical length information.
|
|
;_______________________________________________________________________
|
|
|
|
GetEOFTrap
|
|
BSR FSQueue
|
|
BSR.S RfNCall ; is refnum for a valid open file?
|
|
BNE.S @1 ; br if not . . . (D0=0 if so)
|
|
|
|
MOVE.L FCBEOF(A1,D1),IOLEOF(A0) ; return the logical EOF
|
|
|
|
@1 BRA CmdDone
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: RfNCall
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block
|
|
; D0.W (output) -- file not open, bad refnum errs
|
|
; D1.W (output) -- offset from (A1) to FCB requested
|
|
; (i.e., (A1,D1) points at requested FCB)
|
|
; D2.L (output) -- file number
|
|
; A1.L (output) -- pointer to FCB buffer start
|
|
; A2.L (output) -- VCB pointer
|
|
; Status flags set according to D0.
|
|
; All other registers are preserved.
|
|
; Called by: FileClose,FileRead,GetEOF,TstMod
|
|
; Function: Get the refnum from the param list and return a pointer to
|
|
; the FCB.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 02 Dec 82 LAK Reworked format.
|
|
; 08 Dec 82 LAK Changed refnum validity check. Modified for new FCB structure.
|
|
; Status flags set according to D0.
|
|
; 20 Dec 82 LAK Changed to return VCB pointer in A2 if all is cool.
|
|
; 06 Jun 83 LAK Changed to call ExtOffLinCk (support for offline, ext fs vols)
|
|
; 02 Aug 84 GSS Inserted patch from MSFileFix to save VCB ptr in ReqstVol
|
|
;_______________________________________________________________________
|
|
|
|
RfNCall:
|
|
MOVE.L jRfNCall,-(SP) ; jumptable entry for vRfNCall <29Oct85>
|
|
RTS ; go there <29Oct85>
|
|
vRfNCall ; 'vectored' RfNCall routine <29Oct85>
|
|
|
|
MOVE.L FCBSPtr,A1 ; get ptr to FCBs
|
|
MOVEQ #0,D1 ; clear D1 high word
|
|
MOVE.W IORefNum(A0),D1 ; get refnum
|
|
|
|
BSR.S CkFileRfn ; validate the refnum as an FCB index <01Oct85>
|
|
BNE.S @1 ; br if bad or file not open <01Oct85>
|
|
|
|
MOVE.L FCBFlNm(A1,D1),D2 ; get the file's filenum <01Oct85>
|
|
|
|
MOVE.L FCBVPTR(A1,D1),A2 ; get VCB pointer, too
|
|
MOVE.L A2, ReqstVol
|
|
BSR ExtOffLinCk ; make sure it's on-line and for us
|
|
|
|
@1 TST D0 ; zero if refnum is ok . . .
|
|
RTS ; that's all folks...
|
|
|
|
; D1 now holds a valid refNum (?) - check it before returning it...
|
|
|
|
CkFileRfn:
|
|
MOVEQ #RfNumErr,D0 ; Be pessimistic here...
|
|
MOVEQ #0,D2 ; Clear upper half of D2
|
|
MOVE.W D1,D2 ; Copy for check
|
|
DIVU FSFCBLen,D2 ; Divide by FCB size <03Feb87>
|
|
SWAP D2 ; Get remainder in low word
|
|
SUBQ.W #2,D2 ; Remainder had better be 2 (length word)
|
|
BNE.S @2 ; If not, that's a bad refnum
|
|
|
|
CMP.W (A1),D1 ; Refnum within range?
|
|
BCC.S @2 ; If too high, that's too bad.
|
|
MOVEQ #FNOpnErr,D0 ; Is this file actually open?
|
|
TST.L 0(A1,D1) ; Check File number
|
|
BEQ.S @2 ; Sigh - and we were so close...
|
|
MOVEQ #0,D0 ; It's open - complete success!
|
|
|
|
@2 TST.W D0 ; Set condition codes
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: TstMod,TstMod1 (has A1,D1 set up instead of A0)
|
|
; (c) 1983 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IORefNum
|
|
; D0.W (output) -- 0 if file writable, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Called By: FileWrite,SetEOF,FileAlloc
|
|
; Function: Test if a file is open, and if so, if it may be written to.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 21 Dec 82 LAK Modified for new file system data structures.
|
|
; 17 Jan 83 LAK Changed for write bit location change.
|
|
;_______________________________________________________________________
|
|
|
|
TstMod
|
|
MOVE.L jTstMod,-(SP) ; jump table entry for vTstMod <27Oct86>
|
|
RTS ; go there <27Oct86>
|
|
vTstMod ; 'vectored' TstMod routine <27Oct86>
|
|
|
|
BSR.S RFnCall ; first see if it's open
|
|
BNE.S TMExit ; if not, all done
|
|
|
|
TstMod1 ; entry used by FClose (A0 not set up) <14Jan86>
|
|
MOVEQ #WrPermErr,D0 ; check if file opened for write
|
|
BTST #FCBWrtBit,FCBMdRByt(A1,D1.W)
|
|
BEQ.S TMExit ; exit if no write permission
|
|
|
|
BSR CVFlgs ; check if vol locked or wr protected
|
|
TMExit TST.W D0 ; return status flags set on error
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetFCBInfo
|
|
; (c) 1985 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IOVRefNum,IORefNum,IOFCBIndx
|
|
; D0.W (output) -- 0 if FCB found, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls:
|
|
; Function: Return FCB contents
|
|
;
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 21-May-85 PWD New today.
|
|
; 6-Aug-85 PWD Fixed to pass control to external FS AFTER filling in
|
|
; I/O PB fields.
|
|
; 6-Oct-85 PWD Fixed to save I/O PB pointer in A0 for use by ext. FS
|
|
; 13-Oct-85 PWD Changed to reduce code size (at some small cost in speed)
|
|
; 01-Nov-85 PWD Fixed index FCB search (clobbered index if VRefNum specified)
|
|
; 06-Nov-85 PWD Changed to skip volume control files when indexing.
|
|
; <14Jan86> LAK Added ROM75Fix patch (set up A2 in FndFCB for non-indexed GetFCBInfo).
|
|
;_______________________________________________________________________
|
|
|
|
GetFCBInfo:
|
|
BSR FSQueue ; Wait our turn
|
|
BSR.S FndFCB ; Look for the FCB of interest
|
|
BNE.S @95 ; Punt on errors
|
|
|
|
MOVE.W D1,ioRefNum(A0) ; Return refNum to the caller (indexed case) <01Nov85>
|
|
LEA 0(A1,D1),A3 ; Point to FCB
|
|
MOVE.L A0,-(SP) ; Save A0
|
|
LEA ioFCBFlNm(A0),A1 ; Destination is PB <24Sep86>
|
|
MOVEA.L A3,A0 ; Source is FCB
|
|
MOVEQ #ioFIStILen,D0 ; Length of information to straight copy
|
|
_BlockMove ; Copy the first chunk
|
|
MOVEA.L (SP)+,A0 ; Restore IOPB pointer
|
|
MOVE.W VCBVRefNum(A2),ioFCBVRefNum(A0) ; Return volume refNum <24Sep86>
|
|
MOVE.L FCBClmpSize(A3),ioFCBClpSiz(A0) ; File clump size <24Sep86>
|
|
MOVE.L FCBDirID(A3),ioFCBParID(A0) ; Parent directory ID <24Sep86>
|
|
MOVE.L ioFileName(A0),D0 ; Pick up file name pointer
|
|
BEQ.S @80 ; If zero, we're done
|
|
|
|
MOVEA.L D0,A1 ; Make it the desination of _BlockMove
|
|
MOVE.L A0,-(SP) ; Save PB pointer across _BlockMove <PWD 06Oct85>
|
|
LEA FCBCName(A3),A0 ; Source is CName in FCB (loses PB Ptr)
|
|
MOVEQ #1,D0 ; Clear upper bytes in D0, add length byte
|
|
ADD.B (A0),D0 ; Pick up number of bytes to copy
|
|
_BlockMove ; Copy the filename
|
|
MOVEA.L (SP)+,A0 ; Restore pointer to I/O PB <PWD 06Oct85>
|
|
|
|
@80 MOVE.L A2,ReqstVol ; Set up ReqstVol, D1 for external FS <PWD 18Oct85>
|
|
MOVE.L A3,D1 ; Point D1 to FCB for ext. fs <PWD 18Oct85>
|
|
BSR CkExtFS ; One of our volumes? <PWD 18Oct85>
|
|
|
|
@95 BRA CmdDone ; Call it a day
|
|
|
|
FndFCB
|
|
MOVE.L FCBsPtr,A1 ; Point to the FCB array <13Oct85>
|
|
MOVE.W ioRefNum(A0),D1 ; Pick up the refNum supplied, if any <13Oct85>
|
|
MOVE.W ioFCBIndx(A0),D0 ; Get desired FCB by index? <13Oct85>
|
|
BEQ.S @90 ; If zero, request is by RefNum <13Oct85>
|
|
|
|
MOVEQ #0,D2 ; Clear high word <01Nov85>
|
|
MOVE.W ioVRefNum(A0),D2 ; Pick up volume refNum, if supplied <13Oct85>
|
|
BEQ.S @10 ; If none supplied, that's fine. <13Oct85>
|
|
MOVE.W D2,D0 ; Otherwise, set up for search <13Oct85>
|
|
BSR DtrmV1 ; Determine desired volume
|
|
BNE.S @95 ; Punt on errors
|
|
MOVE.L A2,D2 ; Get pointer to VCB <13Oct85>
|
|
MOVE.W ioFCBIndx(A0),D0 ; Recover FCB index <01Nov85>
|
|
|
|
@10 BSR Gt1stFCB ; Point to first FCB
|
|
@20 MOVE.L FCBFlNm(A1,D1),D3 ; FCB in use? <06Nov85>
|
|
BEQ.S @30 ; If fileNum is zero, it's not
|
|
MOVE.L FCBVPtr(A1,D1),A2 ; Point to VCB in question <06Nov85>
|
|
BSR TFSVCBTst ; Looking at a TFS volume? <06Nov85>
|
|
BNE.S @23 ; If not, consider this FCB <06Nov85>
|
|
CMP.L #FSUsrCNID,D3 ; Is this a volume control FCB? <06Nov85>
|
|
BCS.S @30 ; If so, skip it. <06Nov85>
|
|
@23 TST.L D2 ; Looking for a particular volume? <13Oct85>
|
|
BEQ.S @25 ; Nope - it's a match <13Oct85>
|
|
CMP.L FCBVPtr(A1,D1),D2 ; Otherwise, right volume? <13Oct85>
|
|
BNE.S @30 ; Nope - try next FCB
|
|
@25 SUBQ.W #1,D0 ; Match - that's one less to go
|
|
BEQ.S @90 ; If index = 0, this is the one desired
|
|
|
|
@30 BSR GtNxtFCB ; Advance to the next FCB <13Oct85>
|
|
BCS.S @20 ; Keep going as long as there are FCBs <13Oct85>
|
|
|
|
MOVEQ #fnOpnErr,D0 ; we've failed miserably
|
|
BRA.S @95
|
|
|
|
; D1 now holds a valid refNum (?) - check it before returning it...
|
|
|
|
@90 BSR CkFileRfn ; Validate the refnum <01Oct85>
|
|
MOVE.L FCBVPtr(A1,D1),A2 ; Set up VCB pointer (for non-indexed case) <14Jan86>
|
|
|
|
@95 TST.W D0 ; Set condition codes
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: LockRng
|
|
; (c) 1985 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IOVRefNum,IORefNum
|
|
; D0.W (output) -- 0 if successful, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls:
|
|
; Function: Releases exclusive (write) access to a byte range of an open fork.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 16-Oct-85 PWD New today.
|
|
; <27Oct85> PWD Changed to do nothing for local volumes, pending resolution
|
|
; of exact semantics desired.
|
|
;_______________________________________________________________________
|
|
|
|
; Since neither LockRng nor _Unlockrng does anything substantial right now . . .
|
|
|
|
LockRng:
|
|
UnlockRng:
|
|
BSR FSQueue ; Wait our turn
|
|
BSR RfNCall ; Check refNum, ext. FS, etc.
|
|
BNE.S LockExit ; If not, punt right here & now
|
|
|
|
IF 0 THEN ; **************************************** <27Oct85>
|
|
MOVE.W FCBFlags(A1,D1),D3 ; Pick up current flag word
|
|
BSET #FCBFlgLBit,D3 ; Set range locked bit
|
|
BNE.S LockOK ; This is all a NOP if already locked
|
|
BSET #FCBFlgWBit,D3 ; Set write permission bit
|
|
BNE.S LockOK ; Lock is a NOP if file already open for write
|
|
BSR FCBScan ; Check currently open files for other write access paths
|
|
BNE.S LockExit ; Punt on errors
|
|
OKToLock MOVE.W ioRefNum(A0),D1 ; Recover file RefNum
|
|
MOVE.W D3,FCBFlags(A1,D1) ; Set locked/write permission bits
|
|
ENDIF ; **************************************** <27Oct85>
|
|
|
|
LockOK MOVEQ #0,D0
|
|
LockExit BRA CmdDone
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: UnlockRng
|
|
; (c) 1985 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IOVRefNum,IORefNum
|
|
; D0.W (output) -- 0 if successful, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls:
|
|
; Function: Seizes exclusive (write) access to a byte range of an open fork.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 16-Oct-85 PWD New today.
|
|
; <27Oct85> PWD Changed to do nothing for local volumes, pending resolution
|
|
; of exact semantics desired.
|
|
;_______________________________________________________________________
|
|
|
|
IF 0 THEN ; **************************************** <27Oct85>
|
|
BSR FSQueue ; Wait our turn
|
|
BSR.S RfNCall ; Check refNum, ext. FS, etc.
|
|
BNE.S LockExit ; If not, punt right here & now
|
|
|
|
BCLR #FCBWrtLck,FCBMdRByt(A1,D1) ; Clear range locked bit
|
|
BEQ.S LockOK ; If not locked, this is a NOP
|
|
BCLR #FCBWrtBit,FCBMdRByt(A1,D1) ; If locked, clear write allowed now
|
|
|
|
BRA.S LockOK ; And complete sucessfully
|
|
ENDIF ; **************************************** <27Oct85>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FileAlloc
|
|
; (c) 1983 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IORefNum,IOReqCount,IOActCount
|
|
; D0.W (output) -- 0 if file closed ok, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls:
|
|
; Function: Allocate more blocks to a file.
|
|
;
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 21 Dec 82 LAK Modified for new file system data structures; allocates
|
|
; space up to the amount of free space on the disk.
|
|
; 05 Jul 84 GSS Put the MSFileFix patches in line
|
|
; <01Oct85> LAK Combined with MFS file alloc code. Added support for AllocContig.
|
|
;_______________________________________________________________________
|
|
|
|
; Allocate is generally used to reserve space prior to writing to a file. This is common when
|
|
; duplicating or copying a file. It is also done to assure some contiguity to a file for
|
|
; performance reasons, a forewarning to the file system that this file is going to need
|
|
; a certain amount of space.
|
|
;
|
|
; For MFS allocate, we want to use a different entry point than Alloc since we
|
|
; don't really NEED all we ask for (why not change this and really ask for it all? - I
|
|
; see little use in allocating a small amount if more is really needed . . . unless
|
|
; you want to get all remaining space).
|
|
;
|
|
; Allocate really could have many flavors. Contiguous allocation should always be
|
|
; attempted, and so this use of the H-bit is not so useful. Capps and I think that
|
|
; an allocate call which is absolute is more useful: since there is a call to get LEOF
|
|
; but not PEOF (except the costly GetFileInfo), a common need might be to ensure an
|
|
; absolute amount of space in the file; if the H-bit is set, the input parameter might
|
|
; be used as such. My recommendation:
|
|
;
|
|
; (1) Normal allocate remains relative for compatibility reasons; allocation is attempted
|
|
; contiguously, and as much space as possible up to requested space is allocated.
|
|
; (2) If H-bit is set, the allocation is absolute: this becomes a SetPEOF call except
|
|
; that PEOF must be > current LEOF and >= current PEOF for easiest implementation.
|
|
; Allocation is, as always, attempted in a contiguous block. This could also just
|
|
; fall into the SEOF code which would support all options w/o setting the LEOF except
|
|
; on truncations (maybe H-bit set on SetEOF call could be used to mean SetPEOF instead?).
|
|
; If all of allocation cannot be done, then DskFulErr should be returned with no
|
|
; allocation done.
|
|
;
|
|
; Allocation will generally try to exend the file at its end: if this is possible, it
|
|
; should always be done. The question is whether, if this fails, it is better to allocate
|
|
; in the vicinity of the file (non-contiguously), or as close as possible but contiguously
|
|
; at the risk of being far away from the file's current allocation.
|
|
|
|
toAlloc MOVEQ #0,D0 ; assume vanilla ExtendFile options <14Jan86>
|
|
; (also zero for MFS AllocSt call) <14Jan86>
|
|
BSR TFSVCBTst ; is it TFS or is it MFS <01Oct85>
|
|
BNE AllocSt ; allocate as much space as we can (MFS)<14Jan86>
|
|
|
|
BSR TFSBitTst ; H-bit set? <14Jan86>
|
|
BEQ.S @1 ; br if not <14Jan86>
|
|
MOVEQ #kEFContig,D0 ; if H-bit is set, do it contiguous <14Jan86>
|
|
@1 BRA AllocTFS ; <14Jan86>
|
|
|
|
FileAlloc:
|
|
BSR FSQueue ; wait our time
|
|
BSR TstMod ; test if may modify this file
|
|
BNE.S FAlExit ; (also exit for ext fs, offline vols)
|
|
|
|
MOVEQ #0,D6 ; assume we get none
|
|
MOVE.L IOReqCount(A0),D4 ; number of bytes to allocate
|
|
BEQ.S @1 ; br on zero request
|
|
|
|
TST.W VCBFreeBks(A2) ; any free? (this was added as a fix for MFS alloc
|
|
; which had a bug in this case: better to fix it there).
|
|
BEQ.S @1 ; br if not
|
|
|
|
BSR.S toAlloc ; allocate as much space as we can <01Oct85>
|
|
BNE.S FAlExit ; if we don't get it all, then error
|
|
; (we may need to put a TFS option in
|
|
; later to get as much as we can)
|
|
@1 MOVE.L D6,IOActCount(A0) ; report number actually allocated
|
|
BSR.S AdjEOF ; adjust everybody's phys&logical EOF's
|
|
|
|
MOVEQ #DskFulErr,D0 ; assume we didn't get what we wanted
|
|
CMP.L IOReqCount(A0),D6 ; did we?
|
|
BCS.S FAlExit ; exit if not
|
|
MOVEQ #0,D0 ; no error
|
|
|
|
FAlExit BRA CmdDone
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: SetEOF
|
|
; (c) 1983 Apple Computer, Inc.
|
|
;
|
|
; Arguments: A0.L (input) -- pointer to parameter block, uses:
|
|
; IORefNum,IOLEOF
|
|
; D0.W (output) -- 0 if EOF set ok, errcode otherwise
|
|
; This call may be executed asynchronously.
|
|
; Calls: FSQueue,TstMod,GtNxBlk,AdjEOF,DAlBlks,Alloc,CmdDone, GetFilBuf
|
|
; Function: Set a new logical EOF for a particular file. The physical
|
|
; EOF is set to the next block boundary and the current file
|
|
; position will be pinned at this value (this may cause
|
|
; blocks to be deallocated or allocated).
|
|
;
|
|
; This call will reclaim space a file is not using. If the
|
|
; LEOF is set beyond the current physical EOF and there is
|
|
; not enough space on the disk, no change to the file's EOF
|
|
; parameters will be made, and a disk-full error will be reported.
|
|
;
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 22 Dec 82 LAK Modified for new file system data structures; now only
|
|
; takes a logical EOF argument; corrected file shorten
|
|
; code.
|
|
; 06 Mar 83 LAK Fixed bug in SetEOF with IOLEOF = 0 (now deallocates
|
|
; the disk blocks . . .)
|
|
; 03 Aug 84 GSS Patched to invalidate deleted file block in file buffer so
|
|
; that it will not be written out to disk in a subsequent
|
|
; flushfile, etc. This was fixed before in MSFileFix patch
|
|
; at label SetEOFix.
|
|
; 16 May 85 PWD Set up FlushCache options on call.
|
|
; 4-Jun-85 PWD Changed to truncate files at clump boundaries
|
|
; <21Sep85> LAK Changed to call TrashBlocks when shortening a file.
|
|
; <13Oct85> PWD Changed to interpret H-bit set to mean SetPEOF vs. SetLEOF.
|
|
; <28Oct85> PWD Changed to leave clump size rounding to TruncateFile
|
|
;_______________________________________________________________________
|
|
|
|
SetEOFTrap:
|
|
BSR FSQueue
|
|
BSR TstMod ; test if we may modify this file.
|
|
BNE.S SEOFXit ; exit if cannot mod, or not open.
|
|
; (also for ext fs, offline vols)
|
|
MOVE.L IOLEOF(A0),D7 ; get requested logical end of file
|
|
MOVE.L D7,D4 ; and copy it
|
|
SUB.L FCBPLen(A1,D1.W),D4 ; compare with current PEOF
|
|
BHI.S lngthnFil ; it's longer. alloc blks
|
|
BCS.S shrtnFil ; it's shorter. dealloc blks if we can
|
|
; same length needs no extra treatment
|
|
|
|
; The file positions should be ordered <13Oct85>
|
|
; <13Oct85>
|
|
; CrPs <= LEOF <= PEOF (D7) <13Oct85>
|
|
; <13Oct85>
|
|
; The LEOF (and consequently, the CrPs) is only adjusted if the new PEOF is LOWER <13Oct85>
|
|
|
|
SEOFOK BSR TFSBitTST ; Check: was T(H)TFS bit set? <13Oct85>
|
|
BEQ.S @3 ; If not, adjust the LEOF as requested <13Oct85>
|
|
|
|
CMP.L FCBEOF(A1,D1.W),D7 ; Is new PEOF < current LEOF? <13Oct85>
|
|
BCC.S @5 ; If not, current LEOF is still valid. <13Oct85>
|
|
|
|
@3 MOVE.L D7,FCBEOF(A1,D1.W) ; set the new LEOF
|
|
CMP.L FCBCrPs(A1,D1.W),D7 ; is current position set past this?
|
|
BCC.S @5 ; br if not
|
|
MOVE.L D7,FCBCrPs(A1,D1.W) ; if so, pin to this
|
|
|
|
@5 BSR.S AdjEOF ; adjust any other FCBs for this file
|
|
|
|
MOVEQ #0,D0
|
|
SEOFXit BRA CmdDone
|
|
|
|
; Shorten the file. If setting length to zero, zero start block, phys EOF fields
|
|
; Else mark last block with 001, and dealloc the following blks
|
|
|
|
shrtnFil BSR TFSVolTst ; is it TFS, no, then let MFS handle
|
|
BNE.S MFSShrtnF ; the call
|
|
|
|
MOVE.L D7,D4 ; Recover requested LEOF
|
|
|
|
;<28Oct85> MOVEM.L D0-D1,-(SP) ; Save scratch regs. across call <22Sep85>
|
|
;<28Oct85> MOVE.L D4,D0 ; Get new EOF <22Sep85>
|
|
;<28Oct85> MOVE.L FCBClmpSize(A1,D1),D1 ; Get clump size for file <22Sep85>
|
|
;<28Oct85> BSR RoundAlloc ; Compute new EOF, rounded to clump size <22Sep85>
|
|
;<28Oct85> MULU VCBAlBlkSize+2(A2),D0 ; Compute new EOF in bytes <22Sep85>
|
|
;<28Oct85> MOVE.L D0,D4 ; Stash it for real-life use <22Sep85>
|
|
;<28Oct85> MOVEM.L (SP)+,D0-D1 ; Restore scratch registers <22Sep85>
|
|
|
|
;<28Oct85> CMP.L FCBPLen(A1,D1.W),D4 ; compare with current PEOF
|
|
;<28Oct85> BCC.S SEOFOK ; If D4 is >PEOF, leave it alone. <21Sep85>
|
|
|
|
; Truncate the file space beyond the (rounded) new PEOF:
|
|
|
|
MOVE.L D4,D3 ; used to figure new physical length
|
|
;<14Jan86>;ST FlushOnly ; Set to let TruncateFile round to clump
|
|
MOVEQ #kTFTrunExt,D2 ; set "round to extent" to avoid thrashing <14Jan86>
|
|
JSR TruncateFile ; truncate peof to leof
|
|
BNE.S SEOFXit ; exit if in trouble
|
|
|
|
ShrtnTrash: ; MFS code rejoins here <01Oct85>
|
|
MOVEM.L D0-D2,-(A6) ; now make sure cache is clear <21Sep85>
|
|
MOVE.W D1,D0 ; File refnum <21Sep85>
|
|
MOVE.L FCBPLen(A1,D1.W),D1 ; new PEOF <21Sep85>
|
|
MOVEQ #-1,D2 ; trash all blocks to the end . . . <21Sep85>
|
|
JSR TrashBlocks ; <21Sep85>
|
|
MOVEM.L (A6)+,D0-D2 ; when they may belong to another file . . .<21Sep85>
|
|
BRA.S SEOFOK ; finish up, no errors <21Sep85>
|
|
|
|
lngthnFil JSR Alloc ; need difference from current phys EOF
|
|
BNE.S SEOFXit ; exit if we couldn't get that much
|
|
BRA.S SEOFOK ; otherwise, finish up
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: AdjEOF
|
|
;
|
|
; Arguments: (A1,D1) (input) -- FCB pointer
|
|
; All registers are preserved.
|
|
; Calls: Gt1stFCB,GtNxtFCB
|
|
; Called By: FileWrite,SetEOF,FileAlloc
|
|
; Function: Scan through the FCBs and update any entries with the
|
|
; same filenumber and resouce/regular bit to the same
|
|
; start blk, physical EOF, and logical EOF as the FCB
|
|
; pointed to by (A1,D1). The FCB is marked as modified.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 22 Dec 82 LAK Modified for new file system data structures; now only
|
|
; takes an FCB pointer and preserves all registers.
|
|
; 29 Aug 83 LAK Rewrote to take advantage of FCB field order and
|
|
; Gt1stMatch, GtNxtMatch subroutines.
|
|
; 11-Jul-85 PWD Fixed bug: added code to copy extent record from source FCB
|
|
;_______________________________________________________________________
|
|
|
|
AdjEOF:
|
|
MOVE.L jAdjEOF,-(SP) ; jumptable entry for vAdjEOF <29Oct85>
|
|
RTS ; go there <29Oct85>
|
|
vAdjEOF ; 'vectored' AdjEOF routine <29Oct85>
|
|
|
|
MOVEM.L D0-D6/A0-A5,-(SP) ; preserve all registers
|
|
|
|
ADD D1,A1 ; point to entry
|
|
MOVE.L (A1)+,D2 ; FCBFlNm
|
|
BSET #FCBModBit,(A1) ; mark file modified
|
|
MOVE.W (A1),D0 ; save FCBFlags
|
|
MOVEM.L (A1)+,D3-D6/A2 ; FCBSBlk,FCBEOF,FCBPLen,(FCBCrPs),FCBVPtr
|
|
MOVE.W D0,D6 ; FCBMdRByt (in high byte . . .)
|
|
LEA FCBExtRec-FCBBfAdr(A1),A1 ; Point to start of extent record
|
|
MOVEM.L (A1)+,A3-A5 ; Save extent record
|
|
|
|
; now scan thru all FCBs and update those for the same file (we update
|
|
; our own file's fields with the same information)
|
|
|
|
BSR Gt1stMatch ; scan from the beginning
|
|
BNE.S @3 ; exit if no matches found
|
|
@1 LEA FCBFlags(A1,D1),A0 ;
|
|
MOVE.W (A0)+,D0 ; same resource/regular flag bit?
|
|
EOR.W D6,D0
|
|
LSL.W #7,D0 ; get FCBRscBit in carry
|
|
BCS.S @2 ; br if they don't match
|
|
|
|
MOVE.W D3,(A0)+ ; FCBSBlk
|
|
MOVE.L D4,(A0)+ ; FCBEOF
|
|
MOVE.L D5,(A0)+ ; FCBPLen (A0 left pointing at FCBCrPs)
|
|
LEA FCBExtRec+lenXDR-FCBCrPs(A0),A0 ; Point to end of Extent record
|
|
MOVEM.L A3-A5,-(A0) ; Overwrite extent record
|
|
|
|
@2 BSR GtNxtMatch ; go after the next entry
|
|
BEQ.S @1 ; until we've done 'em all
|
|
|
|
@3 MOVEM.L (SP)+,D0-D6/A0-A5 ; leave registers unchanged
|
|
RTS ; that's all folks.
|
|
|
|
|
|
|