home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-05-14 | 22.0 KB | 1,019 lines |
- 11-May-88 21:59:06-MDT,23458;000000000000
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Wed, 11 May 88 21:58:34 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA03479; Wed, 11 May 88 21:23:43 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA29247; Wed, 11 May 88 21:23:37 MDT
- Date: Wed, 11 May 88 21:23:37 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8805120323.AA29247@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: HFSOpen.asm.shar
-
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # 19 HFSOpen.asm
- # 2 HFSOpen.r
- #
- echo 'Extracting HFSOpen.asm.'
- if test -f HFSOpen.asm; then echo 'shar: will not overwrite HFSOpen.asm'; else
- sed 's/^X//' << '________This_Is_The_END________' > HFSOpen.asm
- X; File HFSOpen.TXT
- X;--------------------------------------------------------------------
- X;
- X; HFS Open Patch
- X;
- X; written by Andy Hertzfeld December 1985
- X;
- X; This program installs an init resource that patches the open
- X; and OpenRF calls in the file system to work harder at opening a file.
- X; It navigates the entire HFS catalog if a file isn't found,
- X; only returning "File Not Found" if the file isn't in any
- X; sub-directory. It should let MDS and other programs work
- X; more smoothly with HFS.
- X;
- X;--------------------------------------------------------------------
- X
- XINCLUDE MacTraps.D
- X
- XXDEF START
- X
- X; I/O Equates
- X
- XIOCompletion EQU 12 ;offset to completion routine address
- XIOResult EQU 16 ;offset to I/O result
- XIOFileName EQU 18 ;offset to fileName
- XIOVRefNum EQU 22 ;offset to volume refNum
- XIORefNum EQU 24 ;offset to file refnum
- X
- XIOFileType EQU 26 ;offset to type byte, permissions
- XIOMisc EQU 28 ;offset to misc param
- XIOBuffer EQU 32 ;offset to buffer pointer
- XIOByteCount EQU 36 ;offset to count
- XIONumDone EQU 40 ;offset to number done
- XIOPosMode EQU 44 ;offset to positioning mode
- XIOPosOffset EQU 46 ;offset to position value
- XIODirID EQU 48 ;offset to directory ID
- X
- XCSCode EQU 26 ;control code offset
- XCSParam EQU 28 ;control parameter offset
- X
- X; low memory equates
- X
- XKeyMap EQU $174 ;keyboard bitmap
- XVCBQueue EQU $356 ;VCB Queue Header
- XFCBSize EQU $3F6 ;new file system FCB size
- XCurApRefNum EQU $900 ;our own refNum
- X
- X
- XStartOfInit
- X BRA InstallIt
- X
- X
- X
- X
- X
- X; first run the normal system open routine and see what kind of errors
- X; we get.
- X
- XOpenPatch
- X PEA BackFromOpen
- X MOVE.L OldOpenAddr,-(SP) ;invoke real open routine
- X RTS
- X
- X; we ran it so check out the errors
- X
- XBackFromOpen
- X BEQ.S DoneOpenPatch ;if no errors, we're file
- X CMP.W #-43,D0 ;file not found?
- X BNE.S NormalOpen ;if so, go to work
- X
- X; it was "file not found" so try to search the catalog
- X
- X MOVEQ #0,D0 ;flag it's an open
- X BSR SearchForFile
- X
- X; it's some other error so there's nothing we can do about it
- X
- XNormalOpen
- X TST.W D0 ;fix up condition codes
- XDoneOpenPatch
- X RTS
- X
- X; OpenRF is handled the same as open
- X
- XOpenRFPatch
- X PEA BackFromOpenRF
- X MOVE.L OldOpenRFAddr,-(SP) ;invoke real open routine
- X RTS
- X
- X
- X; we ran it so check out the errors
- X
- XBackFromOpenRF
- X BEQ.S DoneOpenPatch ;if no errors, we're file
- X CMP.W #-43,D0 ;file not found?
- X BNE.S NormalOpen ;if so, go to work
- X
- X; it was "file not found" so try to search the catalog
- X
- X MOVEQ #1,D0 ;flag it's an openRF
- X BSR SearchForFile
- X BRA.S NormalOpen
- X
- X; GetFileInfo handler
- X
- XGFIPatch
- X PEA BackFromGFI
- X MOVE.L GFIAddr,-(SP) ;invoke real open routine
- X RTS
- X
- X; we ran it so check out the errors
- X
- XBackFromGFI
- X BEQ.S DoneGFIPatch ;if no errors, we're file
- X CMP.W #-43,D0 ;file not found?
- X BNE.S NormalGFI ;if so, go to work
- X
- X; if the name is NIL, give up
- X
- X TST.L IOFileName(A0)
- X BEQ.S NormalGFI
- X
- X MOVE.B PatchOff,-(SP) ;disabled?
- X TST.B (SP)+
- X BNE.S NormalGFI ;if so, quit
- X
- X; it was "file not found" so try to search the catalog
- X
- X MOVEQ #2,D0 ;flag it's a GetFileInfo
- X BSR SearchForFile
- X
- X; it's some other error so there's nothing we can do about it
- X
- XNormalGFI
- X TST.W D0 ;fix up condition codes
- X
- XDoneGFIPatch
- X RTS
- X
- X; Delete handler
- X
- XDeletePatch
- X PEA BackFromDelete
- X MOVE.L DeleteAddr,-(SP) ;invoke real open routine
- X RTS
- X
- X; we ran it so check out the errors
- X
- XBackFromDelete
- X BEQ.S DoneDeletePatch ;if no errors, we're file
- X CMP.W #-43,D0 ;file not found?
- X BNE.S NormalDelete ;if so, go to work
- X
- X; it was "file not found" so try to search the catalog
- X
- X MOVEQ #3,D0 ;flag it's a Delete
- X BSR SearchForFile
- X
- X; it's some other error so there's nothing we can do about it
- X
- X
- XNormalDelete
- X TST.W D0 ;fix up condition codes
- XDoneDeletePatch
- X RTS
- X
- X; SetFileInfo handler
- X
- XSFIPatch
- X PEA BackFromSFI
- X MOVE.L SFIAddr,-(SP) ;invoke real open routine
- X RTS
- X
- X; we ran it so check out the errors
- X
- XBackFromSFI
- X BEQ.S DoneSFIPatch ;if no errors, we're file
- X CMP.W #-43,D0 ;file not found?
- X BNE.S NormalSFI ;if so, go to work
- X
- X; if the name is NIL, give up
- X
- X TST.L IOFileName(A0)
- X BEQ.S NormalSFI
- X
- X MOVE.B PatchOff,-(SP) ;disabled?
- X TST.B (SP)+
- X BNE.S NormalSFI ;if so, quit
- X
- X; it was "file not found" so try to search the catalog
- X
- X MOVEQ #5,D0 ;flag it's a SetFileInfo
- X BSR SearchForFile
- X
- X; it's some other error so there's nothing we can do about it
- X
- XNormalSFI
- X TST.W D0 ;fix up condition codes
- X
- XDoneSFIPatch
- X RTS
- X
- X; The CreatePatch is different from the others, since no search is
- X; involved. If there is exactly one colon in the name, parse it
- X; and do the create into the proper subdirectory. It's dangerous, so
- X; only do with option down
- X
- XCreatePatch
- X BTST #2,KeyMap+7
- X BEQ.S OldCreate
- X
- X TST.W FCBSize ;new file system?
- X BPL.S HFSCreate ;if so, skip
- XOldCreate
- X MOVE.L CreateAddr,-(SP) ;handle normally
- X RTS
- X
- XHFSCreate
- X MOVEQ #4,D0 ;flags it's create
- X
- X; SearchForFile examines the file name, parses it into a name/vRefNum
- X; specification, searches the HFS catalog for a matching filename,
- X; and re-runs the call if it finds on.
- X
- XSearchForFile
- X LINK A6,#-258 ;allocate temp space
- X MOVEM.L D2-D4/A0-A3,-(SP) ;save work registers
- X MOVE.L D1,-(SP) ;keep D1 on top
- X
- X MOVE.W D0,-258(A6) ;remember Open/RF selector
- X MOVE.L A0,A3 ;remember pBlock ptr
- X
- X TST.W FCBSize ;HFS installed?
- X BMI SearchFailed ;if not, give up
- X
- X MOVE.L IOFileName(A3),A0 ;get name ptr
- X MOVEQ #0,D0
- X MOVE.B (A0)+,D0 ;get name size
- X
- X CMP.B #':',(A0) ;first character a colon?
- X BEQ SearchFailed ;if so, we failed
- X
- X; loop, searching for the colon
- X
- XScanForColon
- X CMP.B #':',(A0)+ ;got a colon?
- X BEQ FoundColon
- X
- X
- X
- X SUBQ #1,D0 ;more to search?
- X BGT.S ScanForColon ;if so, keep looking
- X
- X; there wasn't a colon in the filename, so better no search, as it
- X; will really slow use down on those optional files. Option key
- X; down and we will...
- X
- X BTST #2,KeyMap+7
- X BEQ SearchFailed
- X
- X MOVE.L IOFileName(A3),A0 ;point to source
- X LEA -256(A6),A1 ;name buffer
- X MOVEQ #0,D0
- X MOVE.B (A0),D0
- X ADDQ #1,D0
- X _BlockMove ;move in the name
- X
- X MOVE.W IOVRefNum(A3),D3 ;get the VRefNum
- X
- X; OK, now search the HFS catalog, looking for the filename at -256(A6)
- X; on the volume whose vRefNum is in D3. Also, handle create mode
- X; specially
- X
- X
- XDoTheSearch
- X CMP.W #4,-258(A6) ;create mode?
- X BEQ.S DoCreate ;if so, handle specially
- X
- X LEA PatchOff,A0
- X ST (A0) ;GFI patch off!
- X
- X MOVE.L LastDirID,D0 ;get last directory ID
- X BEQ SearchFromRoot ;skip 1st search
- X
- X SUBQ #4,SP ;make room for result
- X MOVE.W D3,-(SP) ;push the vRefNum
- X MOVE.L D0,-(SP) ;start at the root
- X PEA -256(A6) ;push file name
- X BSR SearchCatalog
- X MOVE.L (SP)+,D0 ;get the result
- X BEQ SearchFromRoot ;if not found, we failed
- X
- X; OK, we found the filename in a sub-directory, so open it as a
- X; working directory
- X
- XFoundIt
- X LEA PatchOff,A0
- X CLR.B (A0) ;back on again
- X
- X LEA LastDirID,A0 ;point to dirID variable
- X MOVE.L D0,(A0) ;update variable
- X
- X SUB.W #80,SP
- X MOVE.L SP,A0
- X CLR.L IOFileName(A0)
- X MOVE.W D3,IOVRefNum(A0) ;set up vRefNum
- X MOVE.L #'PTCH',28(A0) ;set up proc ID
- X
- X MOVE.L D0,48(A0) ;set up dir ID
- X
- X MOVEQ #1,D0 ;OpenWD trap
- X DC.W $A260 ;new file system call
- X
- X MOVE.W IOVRefNum(A0),D3 ;remember path refNum
- X ADD.W #80,SP
- X
- X; now retry the trap, using the new vRefNum/name
- X
- X MOVE.L (SP),D1 ;recover D1
- X
- X
- X
- X MOVE.L IOFileName(A3),-(SP) ;save old filename
- X MOVE.W IOVRefNum(A3),-(SP) ;save old vRefNum
- X
- X LEA -256(A6),A1 ;get name pointer
- X MOVE.L A1,IOFileName(A3) ;save as the filename
- X MOVE.W D3,IOVRefNum(A3)
- X MOVE.L A3,A0
- X
- X PEA DoneSearch1 ;push return address
- X
- X; compute the trap address using the table
- X
- X MOVE.W -258(A6),D0 ;get switch value
- X ASL.W #2,D0 ;multiply by 4
- X MOVE.L OldOpenAddr(D0),-(SP) ;push address
- X RTS ;go do it
- X
- X; DoCreate does a special create using the parsed file name and
- X; lastDirID. Don't do it if we find 2 colons in the name, though
- X
- XDoCreate
- X MOVE.L IOFileName(A3),A0 ;get name ptr
- X MOVEQ #0,D0 ;clear length
- X MOVEQ #0,D1 ;clear counter
- X MOVE.B (A0)+,D0 ;get length
- XCntColLoop
- X
- X CMP.B #':',(A0)+ ;a colon?
- X BNE.S @0
- X
- X ADDQ #1,D1 ;count it
- X@0
- X SUBQ #1,D0
- X BGT.S CntColLoop
- X
- X SUBQ #1,D1 ;exactly one colon?
- X BNE SearchFailed ;if not, don't proceed
- X
- X; do a special create call, using lastDirID
- X
- X MOVE.L LastDirID,D0
- X
- X BEQ SearchFailed ;make sure there is one
- X
- X SUB.W #80,SP
- X MOVE.L SP,A0
- X
- X LEA -256(A6),A1
- X MOVE.L A1,IOFileName(A0) ;use parsed name
- X MOVE.W D3,IOVRefNum(A0) ;use vRefNum
- X MOVE.L LastDirID,IODirID(A0)
- X CLR.W IOFileType(A0)
- X CLR.L IOMisc(A0)
- X
- X MOVE.W #$A208,D1 ;flag it's HCreate
- X
- X PEA BackFromCreate ;we're done
- X MOVE.L CreateAddr,-(SP) ;push address
- X RTS ;invoke it
- X
- XBackFromCreate
- X ADD.W #80,SP ;pop off pBlock
- X BRA DoneSearchFile ;all done
- X
- X; addresses of the normal receivers for the five patched out routines
- X
- XOldOpenAddr
- X DC.W 0,0
- XOldOpenRFAddr
- X DC.W 0,0
- XGFIAddr
- X DC.W 0,0
- XDeleteAddr
- X DC.W 0,0
- XCreateAddr
- X DC.W 0,0
- XSFIAddr
- X DC.W 0,0
- XPatchOff
- X DC.W 0
- X
- X; all done, so return the result in D0
- X
- XDoneSearch1
- X MOVE.W (SP)+,IOVRefNum(A3)
- X MOVE.L (SP)+,IOFileName(A3)
- XDoneSearchFile
- X LEA PatchOff,A0
- X CLR.B (A0)
- X
- X MOVE.L (SP)+,D1
- X MOVEM.L (SP)+,D2-D4/A0-A3 ;restore registers
- X UNLK A6 ;de-allocate locals
- X
- X
- X TST.W D0
- X
- X RTS ;all done!
- X
- X; handle the case where the search failed, returning "File not Found"
- X; special case create
- X
- XSearchFailed
- X CMP.W #4,-258(A6) ;create mode?
- X BEQ.S @0 ;if so, handle specially
- X
- X MOVEQ #-43,D0 ;return file not found
- X BRA.S DoneSearchFile
- X@0
- X MOVE.L (SP)+,D1
- X MOVEM.L (SP)+,D2-D4/A0-A3
- X UNLK A6
- X BRA OldCreate
- X
- X; we couldn't find it starting from the last one, so search from the root
- X
- XSearchFromRoot
- X MOVE.L LastDirID,D0 ;get last directory
- X
- X SUBQ.L #2,D0 ;was it the root?
- X BEQ.S SearchFailed ;if so, don't do it twice
- X
- X SUBQ #4,SP ;make room for result
- X MOVE.W D3,-(SP) ;push the vRefNum
- X MOVE.L #2,-(SP) ;start at the root
- X PEA -256(A6) ;push file name
- X BSR SearchCatalog
- X MOVE.L (SP)+,D0 ;get the result
- X BNE FoundIt ;if we're lucky we found it
- X BRA.S SearchFailed
- X
- XLastDirID
- X DC.L 0 ;directory from last time
- X
- X; FoundColon handles the case when the passed in name has a colon in it
- X; Use the part up to the colon to determine the vRefNum, and the part
- X; after the colon as the file name
- X
- XFoundColon
- X LEA -256(A6),A1 ;destination
- X SUBQ #1,D0 ;adjust size
- X MOVE.B D0,(A1)+ ;length byte
- X _BlockMove ;move in the rest
- X
- X; now compute the length of the volume name in D1 and try to find
- X; it in the VCB queue
- X
- X MOVEQ #0,D0
- X MOVE.L IOFileName(A3),A1 ;point to beginning of name
- X SUB.L A1,A0 ;compute size
- X MOVE.L A0,D1 ;get size
- X
- X ADDQ.L #1,A1 ;point at first char
- X SUBQ.L #2,D1 ;adjust it
- X BLE.S SearchFailed ;skip if bad spec
- X
- X; now fly through the VCB queue, comparing against the name
- X
- X MOVE.L VCBQueue+2,D0 ;get first volume ptr
- X BEQ.S SearchFailed
- XVCBSearchLoop
- X MOVE.L D0,A2
- X LEA $2C(A2),A0 ;point to volName
- X
- X MOVEQ #0,D0
- X MOVE.B (A0)+,D0 ;get length, point at 1st char
- X SWAP D0
- X MOVE.W D1,D0
- X _CmpString ;compare with string in A1
- X BEQ.S FoundTheVol
- X
- X MOVE.L (A2),D0
- X BNE.S VCBSearchLoop
- X
- X BRA SearchFailed
- X
- X; we found the volume. The name is already at -256(A6) so get the
- X; vRefNum in D3 and dive back in
- X
- XFoundTheVol
- X MOVE.W 78(A2),D3 ;get the vRefNum
- X BRA DoTheSearch
- X
- X
- X; FUNCTION SearchCatalog(vRefNum:INTEGER; curDir: LongInt; fName: Str255):LongInt
- X
- X;
- X; SearchCatalog searches an HFS volume or sub-directory for a file with
- X; a given name It returns the directory ID of the directory
- X; holding the file, or 0 if it couldn't be found.
- X
- X
- XSearchCatalog
- X LINK A6,#-108 ;allocate pBlock
- X CLR.L 18(A6) ;set result to 0
- X
- X; better make sure we're running the new file system
- X
- X TST.W FCBSize ;for now, check new ROM
- X BMI DoneSCatalog ;if not, we're done
- X
- X; first do a file-name specific HGetFileInfo to see if the file is in
- X; the directory.
- X
- X
- X
- X LEA -108(A6),A0 ;point A0 at pBlock
- X LEA 8(A6),A1 ;point at parameters
- X
- X MOVE.L (A1)+,IOFileName(A0) ;set up the name
- X MOVE.L (A1)+,IODirID(A0) ;set up directory ID
- X MOVE.W (A1)+,IOVRefNum(A0) ;set up vRefNum
- X CLR.W IOMisc(A0) ;clear type and index
- X
- X MOVE.L 12(A6),D1 ;get this dirID in D1
- X DC.W $A20C ;HGetFileInfo
- X BEQ.S SCGotIt ;if found, skip
- X
- X; it's not in the current directory, so index through all nodes to
- X; recursively explore the sub-directories
- X
- XCheckSubdirs
- X
- X CLR.L IOFileName(A0) ;don't want the name back
- X MOVE.W #1,IOMisc(A0) ;start with the first one
- XSCatLoop
- X LEA -108(A6),A0 ;point to the pBlock
- X MOVE.L 12(A6),IODirID(A0) ;re-establish directory ID
- X
- X MOVEQ #9,D0 ;HGetCatInfo call
- X DC.W $A260 ;invoke HFS
- X BNE.S DoneSCatalog ;on error, give up
- X
- X; check if the current node is a directory
- X
- X BTST #4,30(A0) ;a directory?
- X BNE.S CallSCAgain ;if so, go handle it
- X
- X; keep looping until we've inspected them all
- X
- XNextSCatalog
- X ADDQ.W #1,IOMisc(A0) ;bump the index
- X BRA.S SCatLoop ;loop until error
- X
- X; the current node is a directory, so call ourselves recursively to
- X; deal with it
- X
- XCallSCAgain
- X SUBQ #4,SP ;make room for result
- X MOVE.W 16(A6),-(SP) ;same vRefNum
- X
- X MOVE.L IODirID(A0),-(SP) ;new directory ID
- X MOVE.L 8(A6),-(SP) ;same file name
- X BSR SearchCatalog ;call ourselves
- X
- X LEA -108(A6),A0 ;re-establish A0
- X MOVE.L (SP)+,D1 ;get directory ID
- X BEQ.S NextSCatalog ;if none, skip
- X
- X; we found it and D1 has the directory ID
- X
- XSCGotIt
- X MOVE.L D1,18(A6) ;return the result
- XDoneSCatalog
- X UNLK A6
- X
- X MOVE.L (SP)+,A0
- X ADD.W #10,SP ;strip parameters
- X JMP (A0)
- X
- X; InstallIt is the routine that installs the above in the system heap
- X
- X
- XInstallIt
- X
- X MOVEM.L A2-A3,-(SP)
- X
- X LEA OldOpenAddr,A1 ;point to saved address table
- X LEA PatchNumbers,A2 ;point to traps to patch
- X LEA PatchAddresses,A3
- X
- X MOVE.W (A2)+,D2 ;get # to do
- XInstallLoop
- X MOVE.W (A2),D0
- X _GetTrapAddress
- X
- X MOVE.L A0,(A1)+ ;save old address
- X
- X LEA StartOfInit,A0 ;get base address
- X ADD.W (A3)+,A0 ;compute address
- X MOVE.W (A2)+,D0 ;get trap number
- X _SetTrapAddress
- X
- X DBRA D2,InstallLoop
- X
- X MOVEM.L (SP)+,A2-A3
- X RTS
- X
- XPatchNumbers
- X DC.W 5 ;6 patches to do
- X DC.W 0,10,12,9,8,13
- XPatchAddresses
- X DC.W OpenPatch-StartOfInit
- X DC.W OpenRFPatch-StartOfInit
- X DC.W GFIPatch-StartOfInit
- X DC.W DeletePatch-StartOfInit
- X DC.W CreatePatch-StartOfInit
- X DC.W SFIPatch-StartOfInit
- X;-------------------------------------------------------------------------
- X;
- X; Here is the code that isn't part of the INIT resource. It receives
- X; control when the application is run and installs the Init resource
- X; in the system resource file.
- X;
- X
- X;--------------------------------------------------------------------------
- X
- XStart
- X
- X; first allocate some zeroed space by clearing it off the stack
- X
- X MOVE #511,D0 ;need about 2K bytes
- XClearLoop
- X CLR.L -(SP)
- X DBRA D0,ClearLoop
- X
- X; initialize QuickDraw and the toolBox
- X
- XInitWorld
- X PEA -4(A5) ;push address of QuickDraw vars
- X _InitGraf ;initialize QuickDraw
- X _InitFonts ;initialize the font manager
- X _InitCursor ;get the arrow cursor
- X _InitWindows ;initialize the window manager
- X
- X _InitMenus ;ditto for menus
- X
- X CLR.L -(SP) ;our recovery proc is NIL
- X _InitDialogs ;initialize dialogs
- X _TEInit ;and text edit, too
- X
- X; display the info box
- X
- X BSR DisplayInfoBox
- X
- X; compute size of INIT resource to be added
- X
- X LEA StartOfInit,A2
- X LEA Start,A0
- X MOVE.L A0,D0
- X SUB.L A2,D0 ;compute size
- X MOVE.L D0,D1 ;remember size
- X
- X; allocate a handle for the INIT resource
- X
- X DC.W $A522 ;allocate a sysHeap handle
- X BNE NoInstall ;if error, punt
- X
- X MOVE.L A0,A3 ;remember it in A3
- X
- X; move in the code
- X
- X MOVE.L A2,A0 ;souce is in A2
- X MOVE.L (A3),A1 ;destination
- X MOVE.L D1,D0 ;set up size
- X _BlockMove ;move it in
- X
- X; make sure it's not already installed
- X
- X CLR -(SP)
- X _SetResLoad ;resource loading off
- X
- X SUBQ #4,SP
- X MOVE.L InitRType,-(SP)
- X PEA OpenPatchName
- X _GetNamedResource
- X MOVE.L (SP)+,D0
- X BEQ FindInitID
- X
- X; it's already there, so remove it
- X
- X MOVE.L D0,-(SP) ;push resource handle
- X
- X CLR.W -(SP)
- X _UseResFile ;use system file
- X
- X _RmveResource ;remove it
- X
- X; compute the ID to use for the INIT resource
- X
- XFindInitID
- X MOVEQ #8,D3 ;start with ID = 8
- X
- XINITIDLoop
- X SUBQ #4,SP
- X MOVE.L InitRType,-(SP) ;push INIT
- X MOVE D3,-(SP) ;push the ID
- X _GetResource
- X
- X MOVE.L (SP)+,D0 ;got it?
- X BEQ.S AddTheInit ;if not, use that ID
- X
- X ADDQ #1,D3
- X CMP.W #32,D3
- X BLT.S INITIDLoop
- X
- X ST -(SP)
- X _SetResLoad
- X
- X MOVEQ #2,D0
- XDoError
- X MOVE D0,-(SP) ;remember entry code
- X
- X SUBQ #2,SP
- X MOVE D0,-(SP)
- X
- X CLR.L -(SP)
- X
- X MOVE.W CurApRefNum,-(SP)
- X _UseResFile
- X
- X _StopAlert
- X ADDQ #2,SP
- X
- X SUBQ #1,(SP)+ ;code 1?
- X BEQ.S Reboot
- X
- X _ExitToShell
- XNoInstall
- X MOVEQ #3,D0
- X BRA.S DoError
- X
- X; Simply reboot
- X
- XReboot
- X RESET
- X
- X; OK, the ID to use is in D3, so we can add the resource
- X
- XAddTheInit
- X ST -(SP)
- X _SetResLoad
- X
- X CLR -(SP)
- X _UseResFile ;use the system file
- X
- X MOVE.L A3,-(SP) ;push the handle
- X MOVE.L InitRType,-(SP) ;push INIT
- X MOVE.W D3,-(SP) ;push the ID
- X
- X PEA OpenPatchName ;push the name
- X _AddResource
- X
- X SUBQ #2,SP
- X _ResError
- X TST.W (SP)+
- X BNE.S NoInstall
- X
- X; set the attributes
- X
- X MOVE.L A3,-(SP) ;push the resource
- X MOVE #82,-(SP) ;sysHeap,locked, changed
- X _SetResAttrs ;set default attributes
- X
- X; write it out then update the resFile
- X
- X MOVE.L A3,-(SP)
- X _WriteResource
- X
- X SUBQ #2,SP
- X _ResError
- X MOVE (SP)+,D0
- X BNE NoInstall
- X
- X CLR.W -(SP)
- X _UpdateResFile
- X
- X SUBQ #2,SP
- X _ResError
- X MOVE (SP)+,D0
- X BNE NoInstall
- X
- X
- X
- X; better flush all the volumes
- X
- X MOVE.L VCBQueue+2,D0
- X SUB.W #80,SP
- X MOVE.L SP,A0
- XFlushLoop
- X MOVE.L D0,A1
- X CLR.L IOFileName(A0)
- X MOVE.W 78(A1),IOVRefNum(A0)
- X _FlushVol
- X
- X MOVE.L (A1),D0
- X BNE.S FlushLoop
- X
- X ADD.W #80,SP
- X
- XSuccessExit
- X
- X MOVEQ #1,D0
- X BRA DoError
- X
- XReleaseIt
- X BRA.S SuccessExit
- X
- X
- X; DisplayInfoBox puts up the initial dialog
- X
- XDisplayInfoBox
- X
- X SUBQ #4,SP ;make space for result
- X MOVE #1,-(SP) ;dialog ID = 1
- X CLR.L -(SP) ;allocate window in heap
- X
- X MOVEQ #-1,D0
- X MOVE.L D0,-(SP) ;frontmost window
- X _GetNewDialog ;make it the dialog
- XWarnSTLoop
- X CLR.L -(SP) ;no filterProc
- X PEA -200(A5) ;place for result
- X _ModalDialog ;let Bruce fetch events
- X
- X MOVE.W -200(A5),D0 ;get result
- X SUBQ #1,D0
- X BEQ.S WarnOK ;if 1, its OK
- X SUBQ #1,D0 ;cancel?
- X BNE.S WarnSTLoop ;if not, loop
- X
- X _DisposDialog
- X ADDQ #4,SP
- X _ExitToShell
- X
- XWarnOK
- X _DisposDialog
- X RTS
- X
- X
- X; strings, etc
- X
- XInitRType
- X DC.B 'INIT'
- XOpenPatchName
- X
- X DC.B 9,'OpenPatch'
- X
- X
- X
- X
- X
- ________This_Is_The_END________
- if test `wc -l < HFSOpen.asm` -ne 874; then
- echo 'shar: HFSOpen.asm was damaged during transit'
- echo ' (should have been 874 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting HFSOpen.r.'
- if test -f HFSOpen.r; then echo 'shar: will not overwrite HFSOpen.r'; else
- sed 's/^X//' << '________This_Is_The_END________' > HFSOpen.r
- X* File HFSOpen.R
- X**************************************
- X*
- X* Resource Definition File for
- X* HFSFix Installer Utility
- X*
- X***************************************
- X
- XMisc:HFSOpen
- XAPPLXXXX
- X
- XINCLUDE Misc:HFSOpenCode
- X
- XTYPE DLOG
- X ,1 (32)
- Xx
- X60 80 276 448
- X
- XVisible NoGoAway
- X1
- X0
- X4
- X
- XTYPE ALRT
- X ,1
- X100 96 228 424
- X1
- X5555
- X
- X ,2
- X100 96 228 424
- X2
- X5555
- X
- X ,3
- X100 96 228 424
- X3
- X5555
- X
- XTYPE DITL
- X ,1
- X2
- X
- XButton
- X92 40 116 90
- XOK
- X
- XStatText
- X12 64 72 300
- XHFSFix was successfully installed! Click OK to return to reboot and ++
- Xactivate the fix.
- X
- X ,2
- X2
- X
- XButton
- X92 40 116 90
- XOK
- X
- XStatText
- X12 64 72 300
- XToo many INIT resource are already installed on this disk
- X
- X ,3
- X2
- X
- XButton
- X92 40 116 90
- XOK
- X
- XStatText
- X12 64 72 300
- XThere was an error during the installation. Sorry, but HFSFix can't ++
- Xbe installed on this disk.
- X
- X ,4
- X4
- X
- XButton
- X164 40 180 90
- XOK
- X
- XButton
- X164 120 180 170
- XCancel
- X
- XStatText Disabled
- X12 12 28 340
- XHFSFix Installer by Andy Hertzfeld
- X
- XStatText Disabled
- X
- X52 40 164 340
- X
- XThis program will install a resource in your system file that will ++
- Xpatch the file system "Open" command to make it try harder to find a ++
- Xfile. It will find a file no matter what folder it is in, thus making ++
- Xmore programs work with HFS.
- X
- ________This_Is_The_END________
- if test `wc -l < HFSOpen.r` -ne 99; then
- echo 'shar: HFSOpen.r was damaged during transit'
- echo ' (should have been 99 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-