home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / shar_hfs.sit < prev    next >
Encoding:
Text File  |  1988-05-14  |  22.0 KB  |  1,019 lines

  1. 11-May-88 21:59:06-MDT,23458;000000000000
  2. Return-Path: <u-lchoqu%sunset@cs.utah.edu>
  3. Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Wed, 11 May 88 21:58:34 MDT
  4. Received: by cs.utah.edu (5.54/utah-2.0-cs)
  5.     id AA03479; Wed, 11 May 88 21:23:43 MDT
  6. Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
  7.     id AA29247; Wed, 11 May 88 21:23:37 MDT
  8. Date: Wed, 11 May 88 21:23:37 MDT
  9. From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
  10. Message-Id: <8805120323.AA29247@sunset.utah.edu>
  11. To: rthum@simtel20.arpa
  12. Subject: HFSOpen.asm.shar
  13.  
  14. #! /bin/sh
  15. #
  16. # This is a shell archive.  Save this into a file, edit it
  17. # and delete all lines above this comment.  Then give this
  18. # file to sh by executing the command "sh file".  The files
  19. # will be extracted into the current directory owned by
  20. # you with default permissions.
  21. #
  22. # The files contained herein are:
  23. #
  24. #   19 HFSOpen.asm
  25. #    2 HFSOpen.r
  26. #
  27. echo 'Extracting HFSOpen.asm.'
  28. if test -f HFSOpen.asm; then echo 'shar: will not overwrite HFSOpen.asm'; else
  29. sed 's/^X//' << '________This_Is_The_END________' > HFSOpen.asm
  30. X; File HFSOpen.TXT
  31. X;--------------------------------------------------------------------
  32. X;
  33. X;     HFS Open Patch
  34. X;
  35. X;        written by Andy Hertzfeld  December 1985
  36. X;
  37. X;  This program installs an init resource that patches the open 
  38. X;  and OpenRF calls in the file system to work harder at opening a file.
  39. X;  It navigates the entire HFS catalog if a file isn't found,
  40. X;  only returning "File Not Found" if the file isn't in any
  41. X;  sub-directory.  It should let MDS and other programs work
  42. X;  more smoothly with HFS.
  43. X;
  44. X;--------------------------------------------------------------------
  45. X
  46. XINCLUDE MacTraps.D
  47. X
  48. XXDEF        START
  49. X
  50. X; I/O Equates
  51. X
  52. XIOCompletion    EQU    12        ;offset to completion routine address
  53. XIOResult    EQU    16        ;offset to I/O result
  54. XIOFileName    EQU    18        ;offset to fileName
  55. XIOVRefNum    EQU    22        ;offset to volume refNum
  56. XIORefNum    EQU    24        ;offset to file refnum
  57. X
  58. XIOFileType    EQU    26        ;offset to type byte, permissions
  59. XIOMisc        EQU    28        ;offset to misc param
  60. XIOBuffer    EQU    32        ;offset to buffer pointer
  61. XIOByteCount    EQU    36        ;offset to count
  62. XIONumDone    EQU    40        ;offset to number done
  63. XIOPosMode    EQU    44        ;offset to positioning mode
  64. XIOPosOffset    EQU    46        ;offset to position value
  65. XIODirID        EQU    48        ;offset to directory ID
  66. X
  67. XCSCode        EQU    26        ;control code offset
  68. XCSParam        EQU    28        ;control parameter offset
  69. X
  70. X; low memory equates
  71. X
  72. XKeyMap        EQU    $174        ;keyboard bitmap
  73. XVCBQueue    EQU    $356        ;VCB Queue Header
  74. XFCBSize        EQU    $3F6        ;new file system FCB size
  75. XCurApRefNum    EQU    $900        ;our own refNum
  76. X
  77. X
  78. XStartOfInit
  79. X        BRA    InstallIt
  80. X
  81. X
  82. X
  83. X
  84. X
  85. X; first run the normal system open routine and see what kind of errors
  86. X; we get.
  87. X
  88. XOpenPatch
  89. X        PEA    BackFromOpen
  90. X        MOVE.L    OldOpenAddr,-(SP)    ;invoke real open routine
  91. X        RTS
  92. X
  93. X; we ran it so check out the errors
  94. X
  95. XBackFromOpen
  96. X        BEQ.S    DoneOpenPatch        ;if no errors, we're file
  97. X        CMP.W    #-43,D0            ;file not found?
  98. X        BNE.S    NormalOpen        ;if so, go to work
  99. X
  100. X; it was "file not found" so try to search the catalog
  101. X
  102. X        MOVEQ    #0,D0            ;flag it's an open
  103. X        BSR     SearchForFile
  104. X
  105. X; it's some other error so there's nothing we can do about it
  106. X
  107. XNormalOpen
  108. X        TST.W    D0            ;fix up condition codes
  109. XDoneOpenPatch
  110. X        RTS
  111. X        
  112. X; OpenRF is handled the same as open
  113. X
  114. XOpenRFPatch
  115. X        PEA    BackFromOpenRF
  116. X        MOVE.L    OldOpenRFAddr,-(SP)    ;invoke real open routine
  117. X        RTS
  118. X
  119. X
  120. X; we ran it so check out the errors
  121. X
  122. XBackFromOpenRF
  123. X        BEQ.S    DoneOpenPatch        ;if no errors, we're file
  124. X        CMP.W    #-43,D0            ;file not found?
  125. X        BNE.S    NormalOpen        ;if so, go to work
  126. X
  127. X; it was "file not found" so try to search the catalog
  128. X
  129. X        MOVEQ    #1,D0            ;flag it's an openRF
  130. X        BSR     SearchForFile
  131. X        BRA.S    NormalOpen
  132. X                
  133. X; GetFileInfo handler
  134. X
  135. XGFIPatch
  136. X        PEA    BackFromGFI
  137. X        MOVE.L    GFIAddr,-(SP)    ;invoke real open routine
  138. X        RTS
  139. X
  140. X; we ran it so check out the errors
  141. X
  142. XBackFromGFI
  143. X        BEQ.S    DoneGFIPatch        ;if no errors, we're file
  144. X        CMP.W    #-43,D0            ;file not found?
  145. X        BNE.S    NormalGFI        ;if so, go to work
  146. X
  147. X; if the name is NIL, give up
  148. X
  149. X        TST.L    IOFileName(A0)
  150. X        BEQ.S    NormalGFI
  151. X
  152. X        MOVE.B    PatchOff,-(SP)        ;disabled?
  153. X        TST.B    (SP)+
  154. X        BNE.S    NormalGFI        ;if so, quit
  155. X        
  156. X; it was "file not found" so try to search the catalog
  157. X
  158. X        MOVEQ    #2,D0            ;flag it's a GetFileInfo
  159. X        BSR     SearchForFile
  160. X
  161. X; it's some other error so there's nothing we can do about it
  162. X
  163. XNormalGFI
  164. X        TST.W    D0            ;fix up condition codes
  165. X
  166. XDoneGFIPatch
  167. X        RTS
  168. X
  169. X; Delete handler
  170. X
  171. XDeletePatch
  172. X        PEA    BackFromDelete
  173. X        MOVE.L    DeleteAddr,-(SP)    ;invoke real open routine
  174. X        RTS
  175. X
  176. X; we ran it so check out the errors
  177. X
  178. XBackFromDelete
  179. X        BEQ.S    DoneDeletePatch        ;if no errors, we're file
  180. X        CMP.W    #-43,D0            ;file not found?
  181. X        BNE.S    NormalDelete        ;if so, go to work
  182. X
  183. X; it was "file not found" so try to search the catalog
  184. X
  185. X        MOVEQ    #3,D0            ;flag it's a Delete
  186. X        BSR     SearchForFile
  187. X
  188. X; it's some other error so there's nothing we can do about it
  189. X
  190. X
  191. XNormalDelete
  192. X        TST.W    D0            ;fix up condition codes
  193. XDoneDeletePatch
  194. X        RTS
  195. X
  196. X; SetFileInfo handler
  197. X
  198. XSFIPatch
  199. X        PEA    BackFromSFI
  200. X        MOVE.L    SFIAddr,-(SP)    ;invoke real open routine
  201. X        RTS
  202. X
  203. X; we ran it so check out the errors
  204. X
  205. XBackFromSFI
  206. X        BEQ.S    DoneSFIPatch        ;if no errors, we're file
  207. X        CMP.W    #-43,D0            ;file not found?
  208. X        BNE.S    NormalSFI        ;if so, go to work
  209. X
  210. X; if the name is NIL, give up
  211. X
  212. X        TST.L    IOFileName(A0)
  213. X        BEQ.S    NormalSFI
  214. X
  215. X        MOVE.B    PatchOff,-(SP)        ;disabled?
  216. X        TST.B    (SP)+
  217. X        BNE.S    NormalSFI        ;if so, quit
  218. X        
  219. X; it was "file not found" so try to search the catalog
  220. X
  221. X        MOVEQ    #5,D0            ;flag it's a SetFileInfo
  222. X        BSR     SearchForFile
  223. X
  224. X; it's some other error so there's nothing we can do about it
  225. X
  226. XNormalSFI
  227. X        TST.W    D0            ;fix up condition codes
  228. X
  229. XDoneSFIPatch
  230. X        RTS
  231. X
  232. X; The CreatePatch is different from the others, since no search is
  233. X; involved.  If there is exactly one colon in the name, parse it
  234. X; and do the create into the proper subdirectory.  It's dangerous, so
  235. X; only do with option down
  236. X
  237. XCreatePatch
  238. X        BTST    #2,KeyMap+7
  239. X        BEQ.S    OldCreate
  240. X
  241. X        TST.W    FCBSize            ;new file system?            
  242. X        BPL.S    HFSCreate        ;if so, skip
  243. XOldCreate
  244. X        MOVE.L    CreateAddr,-(SP)    ;handle normally
  245. X        RTS
  246. X
  247. XHFSCreate
  248. X        MOVEQ    #4,D0            ;flags it's create
  249. X
  250. X; SearchForFile examines the file name, parses it into a name/vRefNum
  251. X; specification, searches the HFS catalog for a matching filename,
  252. X; and re-runs the call if it finds on.
  253. X
  254. XSearchForFile
  255. X        LINK    A6,#-258        ;allocate temp space
  256. X        MOVEM.L    D2-D4/A0-A3,-(SP)    ;save work registers
  257. X        MOVE.L    D1,-(SP)        ;keep D1 on top
  258. X        
  259. X        MOVE.W    D0,-258(A6)        ;remember Open/RF selector
  260. X        MOVE.L    A0,A3            ;remember pBlock ptr
  261. X
  262. X        TST.W    FCBSize            ;HFS installed?
  263. X        BMI    SearchFailed        ;if not, give up
  264. X        
  265. X        MOVE.L    IOFileName(A3),A0    ;get name ptr
  266. X        MOVEQ    #0,D0
  267. X        MOVE.B    (A0)+,D0        ;get name size
  268. X        
  269. X        CMP.B    #':',(A0)        ;first character a colon?
  270. X        BEQ    SearchFailed        ;if so, we failed
  271. X
  272. X; loop, searching for the colon
  273. X
  274. XScanForColon
  275. X        CMP.B    #':',(A0)+        ;got a colon?
  276. X        BEQ    FoundColon
  277. X
  278. X
  279. X
  280. X        SUBQ    #1,D0            ;more to search?
  281. X        BGT.S    ScanForColon        ;if so, keep looking
  282. X
  283. X; there wasn't a colon in the filename, so better no search, as it
  284. X; will really slow use down on those optional files.  Option key
  285. X; down and we will...
  286. X
  287. X        BTST    #2,KeyMap+7
  288. X        BEQ    SearchFailed
  289. X
  290. X        MOVE.L    IOFileName(A3),A0    ;point to source
  291. X        LEA    -256(A6),A1        ;name buffer
  292. X        MOVEQ    #0,D0
  293. X        MOVE.B    (A0),D0
  294. X        ADDQ    #1,D0
  295. X        _BlockMove            ;move in the name
  296. X                                
  297. X        MOVE.W    IOVRefNum(A3),D3    ;get the VRefNum
  298. X        
  299. X; OK, now search the HFS catalog, looking for the filename at -256(A6)
  300. X; on the volume whose vRefNum is in D3.  Also, handle create mode
  301. X; specially
  302. X
  303. X
  304. XDoTheSearch
  305. X        CMP.W    #4,-258(A6)        ;create mode?
  306. X        BEQ.S    DoCreate        ;if so, handle specially
  307. X        
  308. X        LEA    PatchOff,A0
  309. X        ST    (A0)            ;GFI patch off!
  310. X        
  311. X        MOVE.L    LastDirID,D0        ;get last directory ID
  312. X        BEQ    SearchFromRoot        ;skip 1st search
  313. X
  314. X        SUBQ    #4,SP            ;make room for result
  315. X        MOVE.W    D3,-(SP)        ;push the vRefNum        
  316. X        MOVE.L    D0,-(SP)        ;start at the root
  317. X        PEA    -256(A6)        ;push file name
  318. X        BSR    SearchCatalog
  319. X        MOVE.L    (SP)+,D0        ;get the result
  320. X        BEQ    SearchFromRoot        ;if not found, we failed
  321. X
  322. X; OK, we found the filename in a sub-directory, so open it as a
  323. X; working directory
  324. X
  325. XFoundIt        
  326. X        LEA    PatchOff,A0
  327. X        CLR.B    (A0)            ;back on again
  328. X        
  329. X        LEA    LastDirID,A0        ;point to dirID variable
  330. X        MOVE.L    D0,(A0)            ;update variable
  331. X        
  332. X        SUB.W    #80,SP
  333. X        MOVE.L    SP,A0
  334. X        CLR.L    IOFileName(A0)
  335. X        MOVE.W    D3,IOVRefNum(A0)    ;set up vRefNum
  336. X        MOVE.L    #'PTCH',28(A0)        ;set up proc ID
  337. X
  338. X        MOVE.L    D0,48(A0)        ;set up dir ID
  339. X
  340. X        MOVEQ    #1,D0            ;OpenWD trap
  341. X        DC.W    $A260            ;new file system call
  342. X        
  343. X        MOVE.W    IOVRefNum(A0),D3    ;remember path refNum
  344. X        ADD.W    #80,SP
  345. X
  346. X; now retry the trap, using the new vRefNum/name
  347. X
  348. X        MOVE.L    (SP),D1            ;recover D1
  349. X
  350. X        
  351. X
  352. X        MOVE.L    IOFileName(A3),-(SP)    ;save old filename
  353. X        MOVE.W    IOVRefNum(A3),-(SP)    ;save old vRefNum
  354. X
  355. X        LEA    -256(A6),A1        ;get name pointer
  356. X        MOVE.L    A1,IOFileName(A3)    ;save as the filename
  357. X        MOVE.W    D3,IOVRefNum(A3)
  358. X        MOVE.L    A3,A0
  359. X
  360. X        PEA    DoneSearch1        ;push return address
  361. X
  362. X; compute the trap address using the table
  363. X
  364. X        MOVE.W    -258(A6),D0        ;get switch value
  365. X        ASL.W    #2,D0            ;multiply by 4
  366. X        MOVE.L    OldOpenAddr(D0),-(SP)    ;push address
  367. X        RTS                ;go do it
  368. X
  369. X; DoCreate does a special create using the parsed file name and
  370. X; lastDirID.  Don't do it if we find 2 colons in the name, though
  371. X
  372. XDoCreate
  373. X        MOVE.L    IOFileName(A3),A0    ;get name ptr
  374. X        MOVEQ    #0,D0            ;clear length
  375. X        MOVEQ    #0,D1            ;clear counter
  376. X        MOVE.B    (A0)+,D0        ;get length
  377. XCntColLoop
  378. X
  379. X        CMP.B    #':',(A0)+        ;a colon?
  380. X        BNE.S    @0
  381. X
  382. X        ADDQ    #1,D1            ;count it
  383. X@0
  384. X        SUBQ    #1,D0
  385. X        BGT.S    CntColLoop
  386. X
  387. X        SUBQ    #1,D1            ;exactly one colon?
  388. X        BNE     SearchFailed        ;if not, don't proceed
  389. X
  390. X; do a special create call, using lastDirID
  391. X
  392. X        MOVE.L    LastDirID,D0
  393. X
  394. X        BEQ    SearchFailed        ;make sure there is one
  395. X        
  396. X        SUB.W    #80,SP
  397. X        MOVE.L    SP,A0
  398. X
  399. X        LEA    -256(A6),A1
  400. X        MOVE.L    A1,IOFileName(A0)    ;use parsed name
  401. X        MOVE.W    D3,IOVRefNum(A0)    ;use vRefNum
  402. X        MOVE.L    LastDirID,IODirID(A0)
  403. X        CLR.W    IOFileType(A0)
  404. X        CLR.L    IOMisc(A0)
  405. X        
  406. X        MOVE.W    #$A208,D1        ;flag it's HCreate
  407. X
  408. X        PEA    BackFromCreate        ;we're done
  409. X        MOVE.L    CreateAddr,-(SP)    ;push address
  410. X        RTS                ;invoke it
  411. X
  412. XBackFromCreate
  413. X        ADD.W    #80,SP            ;pop off pBlock
  414. X        BRA    DoneSearchFile        ;all done
  415. X                        
  416. X; addresses of the normal receivers for the five patched out routines
  417. X
  418. XOldOpenAddr
  419. X        DC.W    0,0
  420. XOldOpenRFAddr
  421. X        DC.W    0,0
  422. XGFIAddr
  423. X        DC.W    0,0
  424. XDeleteAddr
  425. X        DC.W    0,0
  426. XCreateAddr
  427. X        DC.W    0,0
  428. XSFIAddr
  429. X        DC.W    0,0
  430. XPatchOff
  431. X        DC.W    0
  432. X                                
  433. X; all done, so return the result in D0
  434. X
  435. XDoneSearch1
  436. X        MOVE.W    (SP)+,IOVRefNum(A3)
  437. X        MOVE.L    (SP)+,IOFileName(A3)
  438. XDoneSearchFile
  439. X        LEA    PatchOff,A0
  440. X        CLR.B    (A0)
  441. X
  442. X        MOVE.L    (SP)+,D1
  443. X        MOVEM.L    (SP)+,D2-D4/A0-A3    ;restore registers
  444. X        UNLK    A6            ;de-allocate locals
  445. X
  446. X
  447. X        TST.W    D0
  448. X
  449. X        RTS                ;all done!
  450. X
  451. X; handle the case where the search failed, returning "File not Found"
  452. X; special case create
  453. X
  454. XSearchFailed
  455. X        CMP.W    #4,-258(A6)        ;create mode?
  456. X        BEQ.S    @0            ;if so, handle specially
  457. X        
  458. X        MOVEQ    #-43,D0            ;return file not found
  459. X        BRA.S    DoneSearchFile
  460. X@0
  461. X        MOVE.L    (SP)+,D1
  462. X        MOVEM.L    (SP)+,D2-D4/A0-A3
  463. X        UNLK    A6
  464. X        BRA    OldCreate
  465. X                        
  466. X; we couldn't find it starting from the last one, so search from the root
  467. X
  468. XSearchFromRoot
  469. X        MOVE.L    LastDirID,D0        ;get last directory
  470. X
  471. X        SUBQ.L    #2,D0            ;was it the root?
  472. X        BEQ.S    SearchFailed        ;if so, don't do it twice
  473. X        
  474. X        SUBQ    #4,SP            ;make room for result
  475. X        MOVE.W    D3,-(SP)        ;push the vRefNum        
  476. X        MOVE.L    #2,-(SP)        ;start at the root
  477. X        PEA    -256(A6)        ;push file name
  478. X        BSR    SearchCatalog
  479. X        MOVE.L    (SP)+,D0        ;get the result
  480. X        BNE    FoundIt            ;if we're lucky we found it
  481. X        BRA.S    SearchFailed
  482. X
  483. XLastDirID
  484. X        DC.L    0            ;directory from last time
  485. X        
  486. X; FoundColon handles the case when the passed in name has a colon in it
  487. X; Use the part up to the colon to determine the vRefNum, and the part
  488. X; after the colon as the file name
  489. X
  490. XFoundColon
  491. X        LEA    -256(A6),A1        ;destination
  492. X        SUBQ    #1,D0            ;adjust size
  493. X        MOVE.B    D0,(A1)+        ;length byte
  494. X        _BlockMove            ;move in the rest
  495. X
  496. X; now compute the length of the volume name in D1 and try to find
  497. X; it in the VCB queue
  498. X
  499. X        MOVEQ    #0,D0
  500. X        MOVE.L    IOFileName(A3),A1    ;point to beginning of name
  501. X        SUB.L    A1,A0            ;compute size
  502. X        MOVE.L    A0,D1            ;get size
  503. X
  504. X        ADDQ.L    #1,A1            ;point at first char
  505. X        SUBQ.L    #2,D1            ;adjust it
  506. X        BLE.S    SearchFailed        ;skip if bad spec
  507. X
  508. X; now fly through the VCB queue, comparing against the name
  509. X
  510. X        MOVE.L    VCBQueue+2,D0        ;get first volume ptr
  511. X        BEQ.S    SearchFailed
  512. XVCBSearchLoop
  513. X        MOVE.L    D0,A2
  514. X        LEA    $2C(A2),A0        ;point to volName
  515. X
  516. X        MOVEQ    #0,D0
  517. X        MOVE.B    (A0)+,D0        ;get length, point at 1st char
  518. X        SWAP    D0
  519. X        MOVE.W    D1,D0
  520. X        _CmpString            ;compare with string in A1
  521. X        BEQ.S    FoundTheVol
  522. X
  523. X        MOVE.L    (A2),D0
  524. X        BNE.S    VCBSearchLoop
  525. X
  526. X        BRA    SearchFailed                                        
  527. X
  528. X; we found the volume.  The name is already at -256(A6) so get the
  529. X; vRefNum in D3 and dive back in
  530. X
  531. XFoundTheVol
  532. X        MOVE.W    78(A2),D3        ;get the vRefNum
  533. X        BRA    DoTheSearch        
  534. X
  535. X
  536. X; FUNCTION SearchCatalog(vRefNum:INTEGER; curDir: LongInt; fName: Str255):LongInt
  537. X
  538. X;
  539. X;    SearchCatalog searches an HFS volume or sub-directory for a file with 
  540. X; a given name   It returns the directory ID of the directory
  541. X; holding the file, or 0 if it couldn't be found.  
  542. X
  543. X
  544. XSearchCatalog
  545. X        LINK    A6,#-108        ;allocate pBlock
  546. X        CLR.L    18(A6)            ;set result to 0
  547. X
  548. X; better make sure we're running the new file system
  549. X
  550. X        TST.W    FCBSize            ;for now, check new ROM
  551. X        BMI    DoneSCatalog        ;if not, we're done
  552. X        
  553. X; first do a file-name specific HGetFileInfo to see if the file is in
  554. X; the directory.
  555. X
  556. X
  557. X
  558. X        LEA    -108(A6),A0        ;point A0 at pBlock
  559. X        LEA    8(A6),A1        ;point at parameters
  560. X        
  561. X        MOVE.L    (A1)+,IOFileName(A0)    ;set up the name
  562. X        MOVE.L    (A1)+,IODirID(A0)    ;set up directory ID
  563. X        MOVE.W    (A1)+,IOVRefNum(A0)    ;set up vRefNum
  564. X        CLR.W    IOMisc(A0)        ;clear type and index
  565. X
  566. X        MOVE.L    12(A6),D1        ;get this dirID in D1
  567. X        DC.W    $A20C            ;HGetFileInfo
  568. X        BEQ.S    SCGotIt            ;if found, skip
  569. X
  570. X; it's not in the current directory, so index through all nodes to 
  571. X; recursively explore the sub-directories
  572. X
  573. XCheckSubdirs
  574. X
  575. X        CLR.L    IOFileName(A0)        ;don't want the name back
  576. X        MOVE.W    #1,IOMisc(A0)        ;start with the first one
  577. XSCatLoop
  578. X        LEA    -108(A6),A0        ;point to the pBlock
  579. X        MOVE.L    12(A6),IODirID(A0)    ;re-establish directory ID
  580. X        
  581. X        MOVEQ    #9,D0            ;HGetCatInfo call
  582. X        DC.W    $A260            ;invoke HFS
  583. X        BNE.S    DoneSCatalog        ;on error, give up
  584. X        
  585. X; check if the current node is a directory
  586. X
  587. X        BTST    #4,30(A0)        ;a directory?
  588. X        BNE.S    CallSCAgain        ;if so, go handle it
  589. X
  590. X; keep looping until we've inspected them all
  591. X
  592. XNextSCatalog
  593. X        ADDQ.W    #1,IOMisc(A0)        ;bump the index
  594. X        BRA.S    SCatLoop        ;loop until error
  595. X        
  596. X; the current node is a directory, so call ourselves recursively to
  597. X; deal with it
  598. X
  599. XCallSCAgain
  600. X        SUBQ    #4,SP            ;make room for result
  601. X        MOVE.W    16(A6),-(SP)        ;same vRefNum
  602. X
  603. X        MOVE.L    IODirID(A0),-(SP)    ;new directory ID
  604. X        MOVE.L    8(A6),-(SP)        ;same file name
  605. X        BSR    SearchCatalog        ;call ourselves
  606. X        
  607. X        LEA    -108(A6),A0        ;re-establish A0
  608. X        MOVE.L    (SP)+,D1        ;get directory ID
  609. X        BEQ.S    NextSCatalog        ;if none, skip
  610. X        
  611. X; we found it and D1 has the directory ID
  612. X
  613. XSCGotIt
  614. X        MOVE.L    D1,18(A6)        ;return the result
  615. XDoneSCatalog
  616. X        UNLK    A6
  617. X        
  618. X        MOVE.L    (SP)+,A0
  619. X        ADD.W    #10,SP            ;strip parameters
  620. X        JMP    (A0)
  621. X        
  622. X; InstallIt is the routine that installs the above in the system heap
  623. X
  624. X
  625. XInstallIt
  626. X
  627. X        MOVEM.L    A2-A3,-(SP)
  628. X        
  629. X        LEA    OldOpenAddr,A1        ;point to saved address table
  630. X        LEA    PatchNumbers,A2        ;point to traps to patch
  631. X        LEA    PatchAddresses,A3
  632. X                
  633. X        MOVE.W    (A2)+,D2        ;get # to do                
  634. XInstallLoop
  635. X        MOVE.W    (A2),D0
  636. X        _GetTrapAddress
  637. X
  638. X        MOVE.L    A0,(A1)+        ;save old address
  639. X
  640. X        LEA    StartOfInit,A0        ;get base address
  641. X        ADD.W    (A3)+,A0        ;compute address
  642. X        MOVE.W    (A2)+,D0        ;get trap number
  643. X        _SetTrapAddress
  644. X
  645. X        DBRA    D2,InstallLoop
  646. X
  647. X        MOVEM.L    (SP)+,A2-A3        
  648. X        RTS
  649. X
  650. XPatchNumbers
  651. X        DC.W    5            ;6 patches to do
  652. X        DC.W    0,10,12,9,8,13
  653. XPatchAddresses
  654. X        DC.W    OpenPatch-StartOfInit
  655. X        DC.W    OpenRFPatch-StartOfInit
  656. X        DC.W    GFIPatch-StartOfInit
  657. X        DC.W    DeletePatch-StartOfInit
  658. X        DC.W    CreatePatch-StartOfInit
  659. X        DC.W    SFIPatch-StartOfInit                
  660. X;-------------------------------------------------------------------------
  661. X;
  662. X;  Here is the code that isn't part of the INIT resource.  It receives
  663. X;  control when the application is run and installs the Init resource
  664. X;  in the system resource file.
  665. X;
  666. X
  667. X;--------------------------------------------------------------------------
  668. X
  669. XStart
  670. X
  671. X; first allocate some zeroed space by clearing it off the stack
  672. X
  673. X        MOVE    #511,D0        ;need about 2K bytes
  674. XClearLoop
  675. X        CLR.L    -(SP)
  676. X        DBRA    D0,ClearLoop
  677. X        
  678. X; initialize QuickDraw and the toolBox
  679. X
  680. XInitWorld
  681. X        PEA    -4(A5)        ;push address of QuickDraw vars
  682. X        _InitGraf              ;initialize QuickDraw
  683. X        _InitFonts        ;initialize the font manager
  684. X        _InitCursor        ;get the arrow cursor
  685. X        _InitWindows        ;initialize the window manager
  686. X
  687. X        _InitMenus        ;ditto for menus
  688. X        
  689. X        CLR.L    -(SP)        ;our recovery proc is  NIL
  690. X        _InitDialogs        ;initialize dialogs
  691. X        _TEInit            ;and text edit, too
  692. X
  693. X; display the info box
  694. X
  695. X        BSR    DisplayInfoBox
  696. X
  697. X; compute size of INIT resource to be added
  698. X
  699. X        LEA    StartOfInit,A2
  700. X        LEA    Start,A0
  701. X        MOVE.L    A0,D0
  702. X        SUB.L    A2,D0            ;compute size
  703. X        MOVE.L    D0,D1            ;remember size
  704. X
  705. X; allocate a handle for the INIT resource
  706. X
  707. X        DC.W    $A522            ;allocate a sysHeap handle        
  708. X        BNE    NoInstall        ;if error, punt
  709. X
  710. X        MOVE.L    A0,A3            ;remember it in A3
  711. X
  712. X; move in the code
  713. X
  714. X        MOVE.L    A2,A0            ;souce is in A2
  715. X        MOVE.L    (A3),A1            ;destination        
  716. X        MOVE.L    D1,D0            ;set up size
  717. X        _BlockMove            ;move it in
  718. X
  719. X; make sure it's not already installed
  720. X
  721. X        CLR    -(SP)
  722. X        _SetResLoad            ;resource loading off
  723. X
  724. X        SUBQ    #4,SP
  725. X        MOVE.L    InitRType,-(SP)
  726. X        PEA    OpenPatchName
  727. X        _GetNamedResource
  728. X        MOVE.L    (SP)+,D0
  729. X        BEQ    FindInitID
  730. X
  731. X; it's already there, so remove it
  732. X
  733. X        MOVE.L    D0,-(SP)        ;push resource handle
  734. X        
  735. X        CLR.W    -(SP)
  736. X        _UseResFile            ;use system file
  737. X        
  738. X        _RmveResource            ;remove it
  739. X
  740. X; compute the ID to use for the INIT resource
  741. X
  742. XFindInitID
  743. X        MOVEQ    #8,D3            ;start with ID = 8
  744. X        
  745. XINITIDLoop
  746. X        SUBQ    #4,SP
  747. X        MOVE.L    InitRType,-(SP)        ;push INIT
  748. X        MOVE    D3,-(SP)        ;push the ID
  749. X        _GetResource
  750. X
  751. X        MOVE.L    (SP)+,D0        ;got it?
  752. X        BEQ.S    AddTheInit        ;if not, use that ID
  753. X
  754. X        ADDQ    #1,D3
  755. X        CMP.W    #32,D3
  756. X        BLT.S    INITIDLoop
  757. X
  758. X        ST    -(SP)
  759. X        _SetResLoad
  760. X        
  761. X        MOVEQ    #2,D0
  762. XDoError        
  763. X        MOVE    D0,-(SP)    ;remember entry code
  764. X        
  765. X        SUBQ    #2,SP
  766. X        MOVE    D0,-(SP)
  767. X
  768. X        CLR.L    -(SP)
  769. X        
  770. X        MOVE.W    CurApRefNum,-(SP)
  771. X        _UseResFile
  772. X        
  773. X        _StopAlert
  774. X        ADDQ    #2,SP
  775. X
  776. X        SUBQ    #1,(SP)+    ;code 1?
  777. X        BEQ.S    Reboot
  778. X        
  779. X        _ExitToShell
  780. XNoInstall
  781. X        MOVEQ    #3,D0
  782. X        BRA.S    DoError
  783. X        
  784. X; Simply reboot
  785. X
  786. XReboot
  787. X        RESET
  788. X
  789. X; OK, the ID to use is in D3, so we can add the resource
  790. X
  791. XAddTheInit
  792. X        ST    -(SP)
  793. X        _SetResLoad
  794. X        
  795. X        CLR    -(SP)
  796. X        _UseResFile            ;use the system file
  797. X        
  798. X        MOVE.L    A3,-(SP)        ;push the handle
  799. X        MOVE.L    InitRType,-(SP)        ;push INIT
  800. X        MOVE.W    D3,-(SP)        ;push the ID
  801. X
  802. X        PEA    OpenPatchName        ;push the name
  803. X        _AddResource
  804. X        
  805. X        SUBQ    #2,SP
  806. X        _ResError
  807. X        TST.W    (SP)+
  808. X        BNE.S    NoInstall
  809. X
  810. X; set the attributes
  811. X
  812. X        MOVE.L    A3,-(SP)        ;push the resource
  813. X        MOVE    #82,-(SP)        ;sysHeap,locked, changed
  814. X        _SetResAttrs            ;set default attributes
  815. X
  816. X; write it out then update the resFile
  817. X
  818. X        MOVE.L    A3,-(SP)
  819. X        _WriteResource
  820. X
  821. X        SUBQ    #2,SP
  822. X        _ResError
  823. X        MOVE    (SP)+,D0
  824. X        BNE    NoInstall
  825. X        
  826. X        CLR.W    -(SP)
  827. X        _UpdateResFile
  828. X        
  829. X        SUBQ    #2,SP
  830. X        _ResError
  831. X        MOVE    (SP)+,D0
  832. X        BNE    NoInstall
  833. X
  834. X
  835. X
  836. X; better flush all the volumes
  837. X
  838. X        MOVE.L    VCBQueue+2,D0
  839. X        SUB.W    #80,SP
  840. X        MOVE.L    SP,A0
  841. XFlushLoop
  842. X        MOVE.L    D0,A1
  843. X        CLR.L    IOFileName(A0)
  844. X        MOVE.W    78(A1),IOVRefNum(A0)
  845. X        _FlushVol
  846. X
  847. X        MOVE.L    (A1),D0
  848. X        BNE.S    FlushLoop
  849. X
  850. X        ADD.W    #80,SP
  851. X
  852. XSuccessExit        
  853. X
  854. X        MOVEQ    #1,D0
  855. X        BRA    DoError
  856. X
  857. XReleaseIt
  858. X        BRA.S    SuccessExit
  859. X        
  860. X        
  861. X; DisplayInfoBox puts up the initial dialog
  862. X
  863. XDisplayInfoBox
  864. X
  865. X        SUBQ    #4,SP            ;make space for result
  866. X        MOVE    #1,-(SP)        ;dialog ID = 1
  867. X        CLR.L    -(SP)            ;allocate window in heap
  868. X
  869. X        MOVEQ    #-1,D0
  870. X        MOVE.L    D0,-(SP)        ;frontmost window
  871. X        _GetNewDialog            ;make it the dialog
  872. XWarnSTLoop
  873. X        CLR.L    -(SP)            ;no filterProc
  874. X        PEA    -200(A5)        ;place for result
  875. X        _ModalDialog            ;let Bruce fetch events
  876. X        
  877. X        MOVE.W    -200(A5),D0        ;get result
  878. X        SUBQ    #1,D0
  879. X        BEQ.S    WarnOK            ;if 1, its OK
  880. X        SUBQ    #1,D0            ;cancel?
  881. X        BNE.S    WarnSTLoop        ;if not, loop
  882. X        
  883. X        _DisposDialog
  884. X        ADDQ    #4,SP
  885. X        _ExitToShell
  886. X        
  887. XWarnOK
  888. X        _DisposDialog
  889. X        RTS
  890. X        
  891. X
  892. X; strings, etc
  893. X
  894. XInitRType
  895. X        DC.B    'INIT'
  896. XOpenPatchName
  897. X
  898. X        DC.B    9,'OpenPatch'
  899. X
  900. X                
  901. X        
  902. X
  903. X
  904. ________This_Is_The_END________
  905. if test `wc -l < HFSOpen.asm` -ne 874; then
  906.     echo 'shar: HFSOpen.asm was damaged during transit'
  907.     echo '      (should have been 874 bytes)'
  908. fi
  909. fi        ; : end of overwriting check
  910. echo 'Extracting HFSOpen.r.'
  911. if test -f HFSOpen.r; then echo 'shar: will not overwrite HFSOpen.r'; else
  912. sed 's/^X//' << '________This_Is_The_END________' > HFSOpen.r
  913. X* File HFSOpen.R
  914. X**************************************
  915. X*
  916. X*  Resource Definition File for
  917. X*    HFSFix Installer Utility
  918. X*
  919. X***************************************
  920. X
  921. XMisc:HFSOpen
  922. XAPPLXXXX
  923. X
  924. XINCLUDE Misc:HFSOpenCode
  925. X
  926. XTYPE DLOG
  927. X  ,1 (32)
  928. Xx
  929. X60 80 276 448
  930. X
  931. XVisible NoGoAway
  932. X1
  933. X0
  934. X4
  935. X
  936. XTYPE ALRT
  937. X  ,1
  938. X100 96 228 424
  939. X1
  940. X5555
  941. X
  942. X  ,2
  943. X100 96 228 424
  944. X2
  945. X5555
  946. X
  947. X  ,3
  948. X100 96 228 424
  949. X3
  950. X5555
  951. X
  952. XTYPE DITL
  953. X  ,1
  954. X2
  955. X
  956. XButton
  957. X92 40 116 90
  958. XOK
  959. X
  960. XStatText
  961. X12 64 72 300
  962. XHFSFix was successfully installed!  Click OK to return to reboot and ++
  963. Xactivate the fix.
  964. X
  965. X  ,2
  966. X2
  967. X
  968. XButton
  969. X92 40 116 90
  970. XOK
  971. X
  972. XStatText
  973. X12 64 72 300
  974. XToo many INIT resource are already installed on this disk
  975. X
  976. X  ,3
  977. X2
  978. X
  979. XButton
  980. X92 40 116 90
  981. XOK
  982. X
  983. XStatText
  984. X12 64 72 300
  985. XThere was an error during the installation.  Sorry, but HFSFix can't ++
  986. Xbe installed on this disk.
  987. X
  988. X  ,4
  989. X4
  990. X
  991. XButton
  992. X164 40 180 90
  993. XOK
  994. X
  995. XButton
  996. X164 120 180 170
  997. XCancel
  998. X
  999. XStatText Disabled
  1000. X12 12 28 340
  1001. XHFSFix Installer by Andy Hertzfeld
  1002. X
  1003. XStatText Disabled
  1004. X
  1005. X52 40 164 340
  1006. X
  1007. XThis program will install a resource in your system file that will ++
  1008. Xpatch the file system "Open" command to make it try harder to find a ++
  1009. Xfile.  It will find a file no matter what folder it is in, thus making ++
  1010. Xmore programs work with HFS.
  1011. X
  1012. ________This_Is_The_END________
  1013. if test `wc -l < HFSOpen.r` -ne 99; then
  1014.     echo 'shar: HFSOpen.r was damaged during transit'
  1015.     echo '      (should have been 99 bytes)'
  1016. fi
  1017. fi        ; : end of overwriting check
  1018. exit 0
  1019.