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

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

1271 lines
38 KiB
Plaintext

;
; File: CommResourceMgrUtilities.a
;
; Contains: Resource chain manipulation routines for the CommResourceMgr
;
; Written by: Byron Han.
; Ported to Assembler by Jerry Godes.
;
; Copyright: © 1989-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <4> 8/12/93 kc <mb>: I deleted all of the "TheFuture" conditionals in all of
; the CommToolbox per Mike Bell's instructions. I also had to
; delete some old code that was compiled under the "CubeE"
; conditional.
; <15> 6/8/92 JSM Fix ProcessMgrExists routine (already conditionalized for
; TheFuture) to match the one in FileMgrPatches.a that looks at
; emProcessMgrExists. Like that file, we may want to invert the
; sense of this routine when we really turn it on so we can just
; do a tst.
; <14> 2/7/92 BH took out constants in CommToolboxPriv.a for resource map
; structure and use constants in ResourceMgrPriv.a
; also set the twoDeep bit after opening the resource file so when
; we splice below the system map we dont screw up the font folder
; <13> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
; <12> 10/2/91 DTY Conditionalise <9> and <10> out of CubeE.
; <11> 7/2/91 BH change routines to prefix with __ to avoid glue conflicts
; <10> 6/25/91 BH bracket all calls to _HOpenResFile and _CloseResFile with
; _BeginSystemMode and _EndSystemMode
; <9> 6/17/91 BH fix problem with CRMReleaseRF which does not set return code
; properly when useCount > 1
; <8> 12/6/90 JNG Don't muck w/ file name in CRMOpenRFPerm <kaz>
; <7> 10/2/90 kaz Changin' ResFileRec field theFile to theName to reflect parity
; in private interface files. <jng>
; <6> 9/10/90 JNG Resolve aliases in CRMOpenRFPerm; Change ResFileRec to use
; canonical file specification.
; <5> 7/2/90 kaz Code shrinkage/cleanup
; <4> 4/11/90 BBH fixed call to CRMFindCommunications to properly setup stack
; (converted to pascal calling conventions instead of internal
; assembler dispatch table convention)
; <3> 4/9/90 BBH removed _CRMFindCommunications
; <2> 3/16/90 BBH make it compile please
; <1> 3/14/90 BBH first checked in
;
; Pre-BBS Modification History
; 1/25/90 BBH Renamed a bunch of routines (added _ before them) to prevent
; conflicts between glue and the toolbox
; 8/3/89 BBH Fixed problem with saving D1 in calling HOpenRFPerm
; Also fixed bug in getting the address of the resource filename
; that is in the resource file record being managed
; 7/27/89 JNG Added CRMGetIndToolName, CRMGetIndFile, CRMFindCommunications,
; CRMCountFiles
; 6/23/89 JNG Start port
;
; To Do:
; ¥ Move CRMGetIndTool etc calls to C and use caching of folder information
; ¥ _CRMCountFiles & _CRMGetIndFile are similar. Try to combine
; ¥ Use StandardEntry routine that loads CTBGlobals & resFiles into a0, a1
;
print push
print off
load 'StandardEqu.d'
INCLUDE 'Aliases.a'
IF (&TYPE('CommToolboxPriv') = 'UNDEFINED') THEN
INCLUDE 'CommToolboxPriv.a'
ENDIF
INCLUDE 'MFPrivate.a' ; <10>
INCLUDE 'GestaltEqu.a' ; <10>
INCLUDE 'ResourceMgrPriv.a' ; <14>
print pop
SysRefNum EQU 2
RomRefNum EQU 1
isAliasBit EQU 15 ; file is an alias
EXPORT __CRMOpenRFPerm, __CRMReserveRF, __CRMReleaseRF, __CRMGetRFCount, __CRMToolPreflight, \
__CRMToolPostflight, __CRMCountFiles, __CRMGetIndFile, \
__CRMGetIndToolName
IMPORT HOpenResFile
; Routine: IsInRMap
; Arguments: refnum - resource file reference number
; Return: true or false
; Behavior: returns TRUE if a resource map with the given refnum is found in the
; resource chain
; Called by: _CRMReleaseRF
; Calls: nothing
; Type: UTILITY
; Register Usage:
; On Entry
; D0 - refnum to look for
;
; Internal
; A0 - Resource map pointer
; D1 - temp to save refnum
; D2 - temp for comparison
;
; On exit
; D0 - 1 if it was found, 0 otherwise
IsInRMap FUNC
movem.l d1-d2,-(SP)
move.w d0,d1
clr.w d0 ; Pessimism
move.l TopMapHndl,a0 ; Get TopMapHndl
@1 move.l a0,d2 ; Is it nil?
beq.s @done ; Yup, no go
move.l (a0),a0 ; Dereference
;-------
CMP.W mRefNum(a0),d1 ; <14>
;-------cmp.w ResourceMapRecord.refNum(a0),d1 ; Do we match
beq.s @2 ; Yup, we're done
;-------
move.l mNext(a0),a0 ; <14>
;-------move.l ResourceMapRecord.next(a0),a0 ; Keep going young man
bra.s @1
@2 move.w #$1,d0
@done movem.l (SP)+,d1-d2
tst.w d0 ; set flag for caller
RTS
DbgInfo.new IsInRMap
ENDF
;=====================================================================================================
;
; Routine: AddResFileRec
; Arguments: none
; Return: resource file record handle if successful, NIL if not
; Behavior: will attempt to allocate a resource file record handle from the
; system heap and will splice record into top of the resource
; file record handle list pointer to off of the CTBGlobal.
; Called by: _CRMOpenRFPerm
; Calls: NewHandleSysClear
; Type: UTILITY
;
; This routine adds a resource file record (an internal CRM data structure) to the top of the
; list of resource files being tracked/managed by the Communications Resource Manager
;
; The data structure is created in the system heap.
;
; If NIL is returned, the data structure was not created.
;
; Register Usage:
; d0 - temp for cmp
; a1 - ResourceFileRecord pointer
; a2 - CTBGlobal data
; On Exit
; a0 - Return value for the ResFileRecHandle
AddResFileRec FUNC
movem.l a1-a2,-(SP)
MOVE.L #ResFileRec.size,D0
_NewHandle sys, clear ; Create the record - we depend on the clear later
move.l a0,d0 ; Check for a valid handle
beq.s @done
move.l (a0),a1 ; dereference it
move.l CommToolboxGlobals,a2 ; Get Global list
move.l CTBBlock.resFiles(a2),ResFileRec.next(a1) ; Next handle
move.l a0,CTBBlock.resFiles(a2) ; Put new one into list
@done movem.l (SP)+,a1-a2
RTS
DbgInfo.new AddResFileRec
ENDF
;=====================================================================================================
;
; Routine: FindResRefNum
; Arguments: _refnum - file reference number
; Return: resource file record handle if found, NIL if not
; Behavior: will attempt to locate a resource file record handle from the
; resource file record list pointed to off of the CTBGlobal.
; Called by: _CRMReserveRF, _CRMReleaseRF, _CRMGetRFCount
; _CRMToolPreflight, _CRMToolPostflight
; Calls: nothing
; Type: UTILITY
;
;=====================================================================================================
; This routine searches the list of resource files tracked by the communications resource
; manager for a record with resource file reference number refnum.
;
; If NIL is returned, the data structure was not found.
;
; Register Usage:
; Entry
; D0 - refnum
; Internal -
; D1 - temp for address comparison
; A1 - dereferenced ResFileRecHdl
; Exit
; A0 - ResFileRecHdl
FindResRefNum FUNC
movem.l d1/a1,-(SP) ; save off temp regs
move.l CommToolboxGlobals,a0 ; Get resource file list
move.l CTBBlock.resFiles(a0),a0
@1 move.l a0,d1 ; Check end of list
beq.s @done
move.l (a0),a1 ; Check matching refnums
cmp.w ResFileRec.refNum(a1),d0
beq.s @done ; We found it - lets take off
move.l ResFileRec.next(a1),a0 ; Onward James
bra.s @1
@done
movem.l (SP)+,d1/a1 ; Restore temp regs
RTS
DbgInfo.new FindResRefNum
ENDF
;=====================================================================================================
;
; Routine: DeleteResFileRec
; Arguments: none
; Return: nothing. will quietly succeed or fail
; Behavior: will attempt to delete a resource file record handle from the
; resource file record list pointed to off of the CTBGlobal.
; Called by: _CRMReleaseRF
; Calls: DisposHandle
; Type: UTILITY
;
;=====================================================================================================
; This routine deletes the given resource file record handle from the list of
; resource files tracked by the communications resource manager.
;
DeleteResFileRec PROC
movem.l a1-a2,-(SP) ; Save Regs
move.l CommToolboxGlobals,a2 ; Get Resource File list
move.l CTBBlock.resFiles(a2),a1
cmp.l a0,a1 ; Are we deleting the first elt?
bne.s @notFirst
move.l (a1),a1 ; Yes, change the header pointer
move.l ResFileRec.next(a1),CTBBlock.resFiles(a2)
bra.s @deleteIt
@notFirst ; Nope, check the next pointers
@1 move.l a1,d0
beq.s @deleteIt ; We're done without finding the item -
; we still want to delete the record passed in
; even though we haven't tracked it
move.l (a1),a1
cmp.l ResFileRec.next(a1),a0 ; Is next the one we want?
bne.s @next
move.l (a0),a2 ; Yup, relink the list
move.l ResFileRec.next(a2),ResFileRec.next(a1)
bra.s @deleteIt
@next
move.l ResFileRec.next(a1),a1 ; Move on to next item
bra.s @1
@deleteIt
_DisposHandle ; Free the data
movem.l (SP)+,a1-a2 ; restore the regs
RTS ; and go home
DbgInfo.new DeleteResFileRec
ENDP
;=====================================================================================================
;
; Routine: _CRMOpenRFPerm
; Arguments: fName - filename, vRefNum - volume reference number, dirID - directory ID
; Return: reference number of file opened, -1 if failed
; Behavior: Searches the resource file record list pointed to off of CTBGlobal.
; (a) If the file has been opened previously with the same current heapZone,
; then return the file reference number
; (b) If the file has been previously opened without the same current heapZone,
; then register the file name, dirID, and vRefNum along with the new
; heapZone as a new entry in the list.
;
; Do a stripaddress on the filename before opening to prevent problems re TN 232
;
; Return the file reference number returned from HOpenResFile.
;
; The resource map is loaded in the current zone. The resource map handle is
; stored in the resource file record.
;
; *** The resource map is removed from the resource map chain. ***
; TopMapHandle is set to the resource file just below the resource file
; opened and cut out of the chain.
; CurMap is set to the new topmost resource file.
;
; (c) If the file has never been opened, do the same as the previous case (b)
;
; <10> modifications
; Set process to system process before opening the file - this allows persistent
; connections to be opened after the process manager is initted and bypasses the
; sanity checking in FSCleanup called from the CleanupApplication trap which
; auto closes all files opened by an application
;
; Called by: Dispatcher
; Calls: CompareFileName, AddResFileRec,
; HOpenResFile, CloseResFile, UseResFile
; Type: INTERNAL
;
; Register Usage
; On Entry -
; A0 - pointer to the parameters (Record defined below)
; Internal -
; d0 - temp (used for checking pointers,lengths in EqualString, address for StripAddress)
; d1 - vRefNum
; d2 - dirID
; d3 - current zone
; d4 - refNum
; d5 - 0 if process mgr exists, 1 otherwise <10>
; a0 - ResFileRecHandle
; a2 - ResFileRec
; a3 - file name
; On Exit -
; D0 - refnum
__CRMOpenRFPerm FUNC
IMPORT ZeroPB,ProcessMgrExists
Parms Record 0
sel DS.W 1
dirID DS.L 1
vRefNum DS.W 1
fName DS.L 1
ENDR
Locals RECORD {A6Link}
LocalStart EQU *
thePB ds.b ioFQElSize
theAlias ds FSSpec
temp ds.w 1
tempName ds.b 64
LocalSize EQU LocalStart -* ; size of all the local variables
A6Link DS.L 1 ; place holder for A6 link
RetAddr DS.L 1 ; place holder for return address
EndR
LINK a6,#Locals.LocalSize
movem.l d1-d5/a1-a3,-(SP) ; added d5 <10>
move.w Parms.vRefNum(a0),d1 ; Save off the parameters into locals
move.l Parms.dirID(a0),d2
move.l Parms.fname(a0),a3
move.l a3,d0
_StripAddress
move.l d0,a3
move.l TheZone,d3
;================================================= start <10>
@pmcheck ; check for process manager
moveq #1,d5 ; does not exist
bsr ProcessMgrExists
bne.s @afterpmcheck
moveq #0,d5 ; does exist
@afterpmcheck
;------------------------------------------------- end <10>
@tryAgain
move.l CommToolboxGlobals,a2 ; Get resource files list
move.l CTBBlock.resFiles(a2),a2
@1 move.l a2,d0 ; End of list?
beq.s @notFound
move.l (a2),a2
cmp.w ResFileRec.theName.vRefNum(a2),d1 ; Matching volumes?
bne.s @next
cmp.l ResFileRec.theName.parID(a2),d2 ; Matching directories?
bne.s @next
cmp.l ResFileRec.pZone(a2),d3 ; Matching heap zones? (Same application)
bne.s @next
clr.l d0 ; Set up for the CmpString
lea.l ResFileRec.theName.name(a2),a0 ; The current res file's name
move.b (a0)+,d0
swap d0
move.l a3,a1 ; The name we're looking for
move.b (a1)+,d0
_CmpString ; This gives case insensitive, diacrit sensitive
beq @found
@next
move.l ResFileRec.next(a2),a2 ; Onwards
bra.s @1
@notfound ; Not recorded
lea Locals.thePB(a6),a0 ; Set up the PB
move.l #ioFQElSize,d0
JSR ZeroPB ; Clear everything
move.w d1,ioVRefNum(a0) ; vRefNum
move.l d2,ioDirID(a0) ; dirID
move.l a3,ioNamePtr(a0) ; Name
_HGetFileInfo
bmi @problem1
move.w ioFlUsrWds + fdFlags(a0),d0
btst #isAliasBit,d0
beq.s @gotRealFile
; We have an alias - resolve it
move.w d1,Locals.theAlias.vRefNum(a6)
move.l d2,Locals.theAlias.parID(a6)
move.l a3,a0
lea Locals.theAlias.name(a6),a1
moveq #32,d0
_BlockMove
subq #2,sp
pea Locals.theAlias(a6)
st -(sp)
pea Locals.temp(a6)
pea Locals.temp(a6)
_ResolveAliasFile
move.w (sp)+,d0
tst.w d0
bne @problem1
move.w Locals.theAlias.vRefNum(a6),d1
move.l Locals.theAlias.parID(a6),d2
lea Locals.theAlias.name(a6),a0
lea Locals.tempName(a6),a1
move.l a1,a3
moveq #32,d0
_BlockMove
bra.s @tryAgain
@gotRealFile
;================================================= start <10>
MOVEM.L D1-D2,-(SP) ; save registers for the duration of the open
; D1 is vrefnum, D2 is dirID
tst.l d5 ; process mgr?
bne.s @afterbegin1
subq.l #2,sp ; space for return value
_BeginSystemMode ; <10>
addq.l #2,sp ; ignore return
@afterbegin1
MOVEM.L (SP),D1-D2 ; changed number of saved registers from D0-D2/A0-A2
;------------------------------------------------- end <10>
clr.w -(SP)
move.w d1,-(SP) ; vRefNum
move.l d2,-(SP) ; dirID
move.l a3,-(SP) ; Name
move.b #fsRdPerm,-(SP) ; Read Only
_HOpenResFile
move.w (SP)+,D4 ; Here's the refnum
;================================================= start <10>
tst.l d5 ; process mgr?
bne.s @afterend1
subq.l #2,sp ; space for return value
_EndSystemMode ; <10>
addq #2,sp
@afterend1
MOVEM.L (SP)+,D1-D2 ; restore vrefnum and dirID
;------------------------------------------------- end <10>
cmp.w #-1,D4 ; Did we have an error
beq.S @problem1
JSR AddResFileRec ; a0 on exit handle to new record
move.l a0,d0
beq.S @problem ; Nil handle
move.l (a0),a2
; Fill in the fields of the ResFileRec
move.l #$40,d0 ; copy all for less code size
move.l a3,a0
lea ResFileRec.theName.name(a2),a1
_BlockMove
move.w d1,ResFileRec.theName.vRefNum(a2)
move.l d2,ResFileRec.theName.parID(a2)
move.w d4,ResFileRec.refNum(a2)
move.l TopMapHndl,ResFileRec.resMap(a2)
move.l d3,ResFileRec.pZone(a2)
; clr.l ResFileRec.useCount(a2) ; These two fields are zeroed since we're doing
; clr.l ResFileRec.reserved(a2) ; a NewHandle, sys, clear
move.l TopMapHndl,a0
move.l (a0),a0
;-------
;-------
MOVE.L mNext(a0),TopMapHndl ; <14>
CLR.L mNext(a0) ; <14>
;-------move.l ResourceMapRecord.next(a0),TopMapHndl
;-------clr.l ResourceMapRecord.next(a0)
; <14>
; this bit is being set because CommToolbox likes to put the resource files
; below the system map while the tool code is being executed
;
; as a result, with the Font Folder changes for Cube E, we need to maintain
; the ability to find font files below the system file (and also below the
; tool file since we splice in just _below_ the system and not at the bottom
; of the resource chain
bset #twoDeepBit,mInMemoryAttr(a0) ; ¥¥¥ <14>
move.l TopMapHndl,a0
move.l (a0),a0
;-------
move.w mRefNum(a0),-(SP) ; <14>
;-------move.w ResourceMapRecord.refNum(a0),-(SP)
_UseResFile
@found
move.w ResFileRec.refNum(a2),d0
bra.s @done
@problem ; let's close down the file now
;================================================= start <10>
tst.l d5 ; process mgr?
bne.s @afterbegin2 ; <10>
subq #2,sp
_BeginSystemMode
addq #2,sp
@afterbegin2
;------------------------------------------------- end <10>
move.w d4,-(SP)
_CloseResFile
;================================================= start <10>
tst.l d5 ; process mgr?
bne.s @afterend2 ; <10>
subq #2,sp
_EndSystemMode
addq #2,sp
@afterend2
;------------------------------------------------- end <10>
@problem1
move.w #-1,d0
@done
movem.l (SP)+,d1-d5/a1-a3 ; added d5 <10>
UNLK a6
RTS
DbgInfo.new CRMOpenRFPerm
ENDF
;=====================================================================================================
;
; Routine: _CRMReserveRF
; Arguments: resource file refnum
; Return: noErr, fnfErr
; Behavior: will attempt to find a resource file record handle from the
; resource file record list pointed to off of the CTBGlobal
; and increment the useCount
; Called by: Dispatcher
; Calls: FindResRefNum
; Type: INTERNAL
;
;=====================================================================================================
; this routine search for the resource file with given reference number in the
; list managed by the comm resource manager and increment the useCount if found.
;
; fnfErr is returned if the file cannot be found.
;
__CRMReserveRF FUNC
Parms RECORD 0
sel DS.W 1
refNum DS.W 1
ENDR
move.w Parms.refNum(a0),d0
JSR FindResRefNum ; Get the ResFileRec, d0 - refnum, a0 - ResFileRecHandle
move.l a0,d0
beq.S @err ; Not in the list
move.l TheZone,d0
move.l (a0),a0
cmp.l ResFileRec.pZone(a0),d0 ; Sanity check - Right zone?
bne.s @err
addq.l #$1,ResFileRec.useCount(a0) ; Bump the use count
moveq.l #$0,d0 ; No error
bra.s @done
@err
move.w #fnfErr,d0 ; couldn't find the resource file
@done
RTS
DbgInfo.new CRMReserveRF
ENDF
;====================================================================================================
;
; Routine: _CRMReleaseRF
; Arguments: resource file refnum
; Return: noErr, fnfErr
; Behavior: will attempt to find a resource file record handle from the
; resource file record list pointed to off of the CTBGlobal
; and decrement the useCount
;
; If useCount goes to zero or negative, we will splice the
; resource file into the resource map chain if necessary and then
; call CloseResFile. The resource file record handle is then
; disposed of.
; Called by: Dispatcher
; Calls: FindResRefNum, IsInRMap, DeleteResFileRec
; Type: INTERNAL
;
; d3 1 if process mgr does not exist <10>
; 0 otherwise
;
__CRMReleaseRF FUNC
IMPORT ProcessMgrExists
Parms RECORD 0
sel DS.W 1
refNum DS.W 1
ENDR
movem.l d1-d3/a1-a3,-(sp) ; added d3 <10>
move.w Parms.refNum(a0),d1
move.w d1,d0
JSR FindResRefNum ; Find the resource file record
move.l a0,d0
beq.s @err ; Is it in there?
move.l a0,a1
move.l (a1),a2
move.l theZone,d2
cmp.l ResFileRec.pZone(a2),d2 ; Sanity check the zone
bne.s @err
subq.l #$1,ResFileRec.useCount(a2) ; We've finished with on use
bgt.s @goodexit ; Someone else is still using it <9> changed to goodexit
move.w d1,d0
JSR IsInRMap ; Is it already inthe map?
bne.s @InMap
move.l ResFileRec.resMap(a2),a0 ; No - put it in so close res file works
move.l (a0),a3
;-------
move.l TopMapHndl,mNext(a3) ; <14>
;-------move.l TopMapHndl,ResourceMapRecord.next(a3)
move.l a0,TopMapHndl
@InMap
;================================================= start <10>
move.w d1,-(sp) ; d1 is volatile. d1 is also the refnum so just save
; thepart we care about
moveq #1,D3 ; no pm
bsr ProcessMgrExists
bne.s @afterbegin3
subq.l #2,sp
_BeginSystemMode
addq.l #2,sp ; ignore return
moveq #0,D3
@afterbegin3
;------------------------------------------------- end <10>
; refnum is already on stack (see above) <10>
_CloseResFile ; Close it
;================================================= start <10>
tst.l d3 ; process mgr?
bne.s @afterend1
subq.l #2,sp
_EndSystemMode
addq #2,sp
@afterend1
;------------------------------------------------- end <10>
move.l a1,a0
JSR DeleteResFileRec ; Remove our record of it
@goodexit ; <9>
clr.w d0 ; return noErr
bra.s @done
@err
move.w #fnfErr,d0
@done
movem.l (sp)+,d1-d3/a1-a3 ; added d3 <10>
RTS
DbgInfo.new CRMReleaseRF
ENDF
;=====================================================================================================
;
; Routine: _CRMGetRFCount
; Arguments: resource file refnum
; Return: noErr, fnfErr
; Behavior: will attempt to find a resource file record handle from the
; resource file record list pointed to off of the CTBGlobal
; and return the useCount
;
; Called by: Dispatcher
; Calls: FindResRefNum
; Type: INTERNAL
;
;=====================================================================================================
; this routine search for the resource file with given reference number in the
; list managed by the comm resource manager and return the useCount if found.
;
; fnfErr is returned if the file cannot be found.
;
; Register Usage
; Entry -
; D0 - refnum
;
__CRMGetRFCount FUNC
Parms Record 0
sel DS.W 1
refNum DS.W 1
ENDR
move.w Parms.refNum(a0),d0 ; get the refNum
JSR FindResRefNum ; D0 - refnum, a0 - ResFileRecHandle
move.l a0,d0
beq.s @err ; Is it in the list?
move.l TheZone,d0
move.l (a0),a0
cmp.l ResFileRec.pZone(a0),d0 ; Sanity check - Right zone?
bne.s @err
move.l ResFileRec.useCount(a0),d0 ; OK just pull out the field
bra.s @done
@err
move.w #fnfErr,d0 ; Couldn't find the resource file
@done
RTS
DbgInfo.new CRMGetRFCount
ENDF
;=====================================================================================================
;
; This routine preflights calls to the communications tool code by manipulating the resource file
; chain. The tool file is placed just BELOW the system file,
;
; the context of the resource chain is stored in the crmContext record including
; procID of the file just below the system file
; was the tool already installed
; the procID of the tool
;
; if -1 is passed in for the procID, we get the procID from the crmContext and
; store the context in the heaplist entry for this zone. this is to allow
; jamming the resource map into the resource list when setup dialog is up
;
__CRMToolPreflight PROC
Parms RECORD 0
sel ds.w 1
crmContext ds.l 1
procID ds.w 1
ENDR
movem.l d1-d2/a1-a4,-(SP)
moveq #$0,d1
move.l a0,a2
move.l Parms.crmContext(a2),a1
move.w Parms.procID(a2),d0
cmp.w #$FFFF,d0 ; Are we being called from Setup
bne.s @regular
move.w CRMToolContext.toolProcID(a1),d0 ; Get the real procID
move.w d0,Parms.procID(a2)
moveq #$1,d1 ; Set our flag
@regular
JSR FindResRefNum ; Now find the file
move.l a0,d0
beq @err ; Not one of ours
move.l TheZone,d2 ; sanity check the zone
move.l (a0),a0
cmp.l ResFileRec.pZone(a0),d2
bne @err ; Wrong zone
; Start filling in the context
move.w #$FFFF,CRMToolContext.oldProcID(a1) ; No oldProcID yet
move.b #$0,CRMToolContext.wasBelow(a1)
move.w Parms.ProcID(a2),CRMToolContext.toolProcID(a1) ; Save off current procID
; A2 is now being converted to be the resMap we are searching for
move.l ResFileRec.resMap(a0),a2
move.l SysMapHndl,a3
move.l (a3),a3
;-------
move.l mNext(a3),CRMToolContext.oldHidden(a1) ; <14>
;-------move.l ResourceMapRecord.next(a3),CRMToolContext.oldHidden(a1) ; OldHidden is first below system
beq.s @nothingHidden ; Above move checks condition codes for us
;-------
move.l mNext(a3),a3 ; <14>
;-------move.l ResourceMapRecord.next(a3),a3
move.l (a3),a4
;-------
move.w mRefNum(a4),CRMToolContext.oldProcID(a1) ; <14>
;-------move.w ResourceMapRecord.refNum(a4),CRMToolContext.oldProcID(a1) ; The previously hidden file
move.l #$0,a4 ; Previous - there isn't any yet
@1 cmp.l a3,a2 ; Is this the resource file?
bne.S @next
move.b #$1,CRMToolContext.wasBelow(a1) ; Yes - mark it as already below
move.l a4,d0 ; Are we on the first one?
beq.S @doneSplice ; Yup - don't touch the list
move.l (a4),a4 ; No - splice it in
move.l (a3),a3
;-------
move.l mNext(a3),mNext(a4) ; <14>
;-------move.l ResourceMapRecord.next(a3),ResourceMapRecord.next(a4) ; PrevRM^^.next := currRM^^.next
bra.s @doneSplice
@next
move.l a3,a4 ; PrevRM := currRM
move.l (a3),a3
;-------
move.l mNext(a3),a3 ; <14>
;-------move.l ResourceMapRecord.next(a3),a3 ; currRM := currRM^^.next
move.l a3,d0
bne.s @1
@nothingHidden
move.l (a2),a3
move.l SysMapHndl,a4
move.l (a4),a4
;-------
;-------
move.l mNext(a4),mNext(a3) ; <14>
move.l a2,mNext(a4) ; <14>
;-------move.l ResourceMapRecord.next(a4),ResourceMapRecord.next(a3) ; currRM := SysRM^^.next
;-------move.l a2,ResourceMapRecord.next(a4) ; SysRM^^.next := currRM
@doneSplice
tst.w d1 ; Is this a special - ie from setup code
beq.s @done
move.w CRMToolContext.OldProcID(a1),ResFileRec.special.OldProcID(a0) ; Yes - we need to save the context
move.l CRMToolContext.oldHidden(a1),ResFileRec.special.OldProcID(a0)
move.w CRMToolContext.toolProcID(a1),ResFileRec.special.toolProcID(a0)
move.b CRMToolContext.wasBelow(a1),ResFileRec.special.wasBelow(a0)
bra.s @done
@err
move.w #fnfErr,d0
bra.s @goHome
@done
move.w #$0,d0
@goHome
movem.l (SP)+,d1-d2/a1-a4
RTS
DbgInfo.new CRMToolPreflight
ENDP
;=====================================================================================================
;
; This routine postflights calls to the communications tool code by manipulating the resource file
; chain into the state that it was in before the _CRMToolPreflight call.
;
; If we need to remove the tool from the resource list and the current map is the system map,
; we need to set the curMap to 0. (system file)
;
; Register Usage
; Entry -
; A0 - pointer to parameters
; Internal
; A0 - pointer to ResFileRec
; A1 - pointer to CRMToolContext
; A2 - prevRM
; A3 - currRM
; A4 - currRM^
;
__CRMToolPostflight PROC
Parms Record 0
sel DS.W 1
crmContext ds.l 1
ENDR
movem.l d0/a1-a4,-(SP)
move.l Parms.crmContext(a0),a1 ; Get context pointer
move.w CRMToolContext.toolprocID(a1),d0 ; find the ResFileRec
JSR FindResRefNum
move.l a0,d0
beq.s @notRegistered ; We're not keeping track of this file
move.l TheZone,d1 ; sanity check the zone
move.l (a0),a0
cmp.l ResFileRec.pZone(a0),d1
bne @done ; Wrong zone
@notRegistered
tst.w CRMToolContext.oldProcID(a1) ; Was prefight called from setup?
bne.s @notSpecial
move.l a0,d0 ; Check again
beq @done ; Now, we have an error - can't restore context1
move.w ResFileRec.special.OldProcID(a0),CRMToolContext.OldProcID(a1) ; Yup - restore context
move.l ResFileRec.special.oldHidden(a0),CRMToolContext.oldHidden(a1)
move.w ResFileRec.special.toolProcID(a0),CRMToolContext.toolProcID(a1)
move.b ResFileRec.special.wasBelow(a0),CRMToolContext.wasBelow(a1)
@notSpecial
tst.w CRMToolContext.oldProcID(a1) ; Was something hiding before?
blt.s @doneSplice ; yes, Splice it back in
move.l #$0,a2 ; PrevRM
move.l SysMapHndl,a3 ; Start searching for it at the system file
move.l (a3),a4
@1
;-------
move.l mNext(a4),a3 ; <14>
;-------move.l ResourceMapRecord.next(a4),a3 ; Can't be the system - so go on one
move.l a3,d0
beq.s @doneSplice ; We're at the end of the list
move.l (a3),a4 ;
cmp.l CRMToolContext.oldHidden(a1),a3 ; Is this the old file?
bne.s @next
move.l a2,d0 ; Yes - Is this the first item in the list?
beq.s @doneSplice
move.l (a2),a2 ; No - splice it in
;-------
move.l mNext(a4),mNext(a2) ; <14>
;-------move.l ResourceMapRecord.next(a4),ResourceMapRecord.next(a2) ; PrevRM^^.next := oldHidden^^.next
move.l SysMapHndl,a2 ; oldHidden^.next := SysMapHndl^^.next
move.l (a2),a2
;-------
;-------
move.l mNext(a2),mNext(a4) ; <14>
move.l a3, mNext(a2); ; <14>
;-------move.l ResourceMapRecord.next(a2),ResourceMapRecord.next(a4)
;-------move.l a3,ResourceMapRecord.next(a2) ; SysMapHndl^^.next := oldHidden;
bra.s @doneSplice
@next
move.l a3,a2
bra.s @1
@doneSplice
tst.b CRMToolContext.wasBelow(a1) ; Was this file previously below?
bne.s @done
move.l a0,d0
beq.s @done
move.l SysMapHndl,a3 ; Yup - splice it back
move.l a3,a2 ; PrevRM
move.l (a3),a4
@2
;-------
move.l mNext(a4),a3
;-------move.l ResourceMapRecord.next(a4),a3
move.l a3,d0
beq.s @done ; We didn't find it
move.l (a3),a4
cmp.l ResFileRec.resMap(a0),a3 ; Do we match?
bne.s @next1 ; nope
move.l (a2),a2 ; We've got a match
;-------
;-------
move.l mNext(a4),mNext(a2) ; <14>
move.l #$0,mNext(a4) ; <14>
;-------move.l ResourceMapRecord.next(a4),ResourceMapRecord.next(a2) ; PrevRM^^.next := currRM^^.next
;-------move.l #$0,ResourceMapRecord.next(a4) ; CurrRM^^.next := nil
move.w CRMToolContext.toolProcID(a1),d0
cmp.w CurMap,d0 ; Did we just play with CurMap?
bne.s @done
move.l TopMapHndl,a3 ; Yup - set CurMap to TopMapHndl
move.l (a3),a3
;-------
move.w mRefNum(a3),CurMap ; <14>
;-------move.w ResourceMapRecord.refNum(a3),CurMap
bra.s @done
@next1
move.l a3,a2
bra.s @2
@done
movem.l (SP)+,d1/a1-a4
RTS
DbgInfo.new CRMToolPostflight
ENDP
; Routine: ZeroPB
; Arguments: Number of bytes to clear, and starting address
; Return: nothing
; Behavior: Clears specified number of bytes
; Called by: _CRMGetIndFile
; Calls: nothing
; Type: UTILITY
; Register Usage:
; On Entry
; D0 - number of Bytes to clear
; A0 - starting Address
;
; Internal
; A0 - Pointer into data
; D0 - remaining # of words
;
ZeroPB PROC ; zeros PB referenced by A0
MOVEM.L D0/A0,-(SP) ; save it
LSR.L #1,D0 ; divide by two (shift right 1)
SUBQ #1,D0 ; subtract one to get translate to 0 base
@TopOfLoop
CLR.W (A0)+ ; clear
DBGT D0,@TopOfLoop ; D0--; if D0>0 go to top
MOVEM.L (SP)+,D0/A0 ; restore it
RTS ; This is an important instruction
ENDPROC
; Routine: _CRMCountFiles
; Arguments: DirID, and VRef num to search in, as well as file type to search for.
; Return: number of files matching input parameters
; Behavior: this routine return the number of files with the given filetype in the folder
; with the given volume reference number and directory ID.
; Called by: Dispatcher
; Calls: _HGetFileInfo
; Type: INTERNAL
; Register Usage:
; On Entry
; A0 - Pointer to parameters
;
; Internal
; A0 - Pointer to PB for file system calls
; A1 - Pointer to Parameters
; D0 - temp
; D1 - index number of files
; D2 - number of matching files
;
; Exit
; D0 - number of matching files
__CRMCountFiles FUNC
IMPORT ZeroPB
Parms RECORD 0
sel ds.w 1
dirID ds.l 1
vRefNum ds.w 1
fType ds.l 1
EndR
Locals RECORD {A6Link}
LocalStart EQU *
thePB ds.b ioFQElSize
LocalSize EQU LocalStart -* ; size of all the local variables
A6Link DS.L 1 ; place holder for A6 link
RetAddr DS.L 1 ; place holder for return address
EndR
LINK a6,#Locals.LocalSize
movem.l d1-d3/a1,-(sp)
move.l a0,a1
move.w #$1,d1 ; Start with file # 1
clr.w d2 ; No matches yet
move.l Parms.fType(a1),d3 ; Save File type
lea Locals.thePB(a6),a0 ; Set up the PB
move.l #ioFQElSize,d0
JSR ZeroPB ; Clear everything
move.w Parms.vRefNum(a1),ioVRefNum(a0)
@1
move.l Parms.dirID(a1),ioDirID(a0) ; DirID gets trashed by HGetFileInfo, so reset
move.w d1,ioFDirIndex(a0)
_HGetFileInfo
bne.s @done ; Trap dispatcher checks D0 for us.
cmp.l ioFlUsrWds+fdType(a0),d3 ; Matching type?
bne.s @noMatch
add.w #$1,d2 ; Yup - add one to count
@noMatch
add.w #$1,d1 ; Next file
bra.s @1
@done
move.w d2,d0 ; give 'em the result
movem.l (sp)+,d1-d3/a1 ; Clean up.
UNLK a6
rts
DbgInfo.new CRMCountFiles
ENDF
; Routine: _CRMGetIndFile
; Arguments: DirID, and VRef num of file, as well as index and type
; Return: name of file matching specifications
; Behavior: this routine return the index-th file with the given filetype in the folder
; with the given volume reference number and directory ID.
; Called by: Dispatcher, _CRMGetIndToolName
; Calls: _HGetFileInfo
; Type: INTERNAL
; Register Usage:
; On Entry
; A0 - Pointer to parameters
;
; Internal
; A0 - Pointer to PB for file system calls
; A1 - Pointer to Parameters
; D0 - temp
; D1 - index number of files
; D2 - number of matching files
;
; Exit
; D0 - OSErr
__CRMGetIndFile FUNC
IMPORT ZeroPB
Parms RECORD 0
sel ds.w 1
index ds.w 1
dirID ds.l 1
vRefNum ds.w 1
fType ds.l 1
fName ds.l 1
EndR
Locals RECORD {A6Link}
LocalStart EQU *
thePB ds.b ioFQElSize
LocalSize EQU LocalStart -* ; size of all the local variables
A6Link DS.L 1 ; place holder for A6 link
RetAddr DS.L 1 ; place holder for return address
EndR
LINK a6,#Locals.LocalSize
movem.l d1-d3/a1,-(sp)
move.l a0,a1
move.w #$1,d1 ; Start with file # 1
clr.w d2 ; No matches yet
move.l Parms.fType(a1),d3 ; Save File type
lea Locals.thePB(a6),a0 ; Set up the PB
move.l #ioFQElSize,d0
JSR ZeroPB ; Clear everything
move.l Parms.fName(a1),ioFileName(a0)
move.w Parms.vRefNum(a1),ioVRefNum(a0)
@1
move.l Parms.dirID(a1),ioDirID(a0) ; DirID gets trashed by HGetFileInfo, so reset
move.w d1,ioFDirIndex(a0)
_HGetFileInfo
bne.s @notFound
cmp.l ioFlUsrWds+fdType(a0),d3 ; Matching type?
bne.s @noMatch
add.w #$1,d2 ; Yup - add one to count
cmp.w Parms.index(a1),d2 ; Are we at the right index?
bne.s @noMatch
clr.w d0
bra.s @done
@noMatch
add.w #$1,d1 ; Next file
bra.s @1
@notFound
move.l Parms.fName(a1),a0
clr.b (a0)
@done
movem.l (sp)+,d1-d3/a1 ; Clean up.
UNLK a6
rts
DbgInfo.new CRMGetIndFile
ENDF
; Routine: _CRMGetIndToolName
; Arguments: Index and Type
; Return: name of file matching specifications
; Behavior: this routine return the index-th file with the given filetype in the Communications
; folder
; Called by: Dispatcher
; Calls: _HGetFileInfo
; Type: EXTERNAL
; Register Usage:
; On Entry
; A0 - Pointer to parameters
;
; Internal
; A0 - Pointer to PB for file system calls
; A1 - Pointer to Parameters
; D0 - temp
; D1 - index number of files
; D2 - number of matching files
;
; Exit
; D0 - OSErr
__CRMGetIndToolName FUNC
IMPORT CRMFindCommunications, CRMCreateCommunications, CRMGetIndFile
Parms Record 0
sel ds.w 1
toolName ds.l 1
index ds.w 1
bundleType ds.l 1
endR
Locals RECORD {A6Link}
LocalStart EQU *
dirID ds.l 1
vRefNum ds.w 1
LocalSize EQU LocalStart -* ; size of all the local variables
A6Link DS.L 1 ; place holder for A6 link
RetAddr DS.L 1 ; place holder for return address
EndR
Link A6,#Locals.LocalSize ; Setup
move.l a2,-(sp) ; save a2
move.l a0,a2
clr.w -(sp) ; return value
pea Locals.vRefNum(a6) ; Does Communications folder exist?
pea Locals.dirID(a6)
JSR CRMFindCommunications
MOVE.W (SP)+,D0
tst.w d0 ; Result in D0
beq.s @FolderExists ; We got the folder
; Why do we create the folder here????
@CreateIt
clr.w -(sp) ; Return value
pea Locals.vRefNum(a6)
pea Locals.dirID(a6)
JSR CRMCreateCommunications ; Both procedures take the same parms
move.w (sp)+,d0
bra.s @done ; just made -> no tools here yet
@FolderExists
; pascal OSErr CRMGetIndFile(Str63 fName, OSType fType, short vRefNum, long dirID, short index);
clr.w -(sp) ; return value
move.l Parms.toolName(a2),-(sp) ; Ok, now get the info on the file
move.l Parms.bundleType(a2),-(sp)
move.w Locals.vRefNum(a6),-(sp)
move.l Locals.DirID(a6),-(sp)
move.w Parms.Index(a2),-(sp)
jsr CRMGetIndFile
@done
move.l (sp)+,a2
UNLK a6
RTS
DbgInfo.new CRMGetIndToolName
ENDF
;
; STOLEN from {sources}OS:HFS:FileMgrPatches.a <10>
;
;________________________________________________________________________________
; Routine: ProcessMgrExists
; Function: check if Process Mgr is running
; Input: none
; Output: D0=0 if it is ready; all other registers are preserved.
; Condition codes = (tst.w d0)
; ________________________________________________________________________________
ProcessMgrExists proc export
move.l a0,-(sp) ; save a0
move.l ExpandMem,a0 ; get ExpandMem <15>
tst.w ExpandMemRec.emProcessMgrExists(a0) ; is Process Mgr up yet? <15>
beq.s @notReady ; no <15>
moveq #0,d0 ; DO = 0 means ready <15>
bra.s @exit ; <15>
@notReady
moveq #1,d0 ; D0 <> 0 means not ready <15>
@exit
movea.l (sp)+,a0 ; d0 = OSErr, noErr if Process Mgr exists
rts ; leave with condition codes intact
endproc
END