; ; 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 : 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 ; <7> 10/2/90 kaz Changin' ResFileRec field theFile to theName to reflect parity ; in private interface files. ; <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