home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / util / diskfile / deskchec.sit / DeskCheck.asm < prev    next >
Encoding:
Assembly Source File  |  1989-02-23  |  23.1 KB  |  852 lines

  1.  
  2. Debug    equ    0        ; make non-zero for debugging
  3.  
  4.     String_Format    0    ; no string padding
  5.  
  6.  
  7. ;    DeskCheck.asm: Find out whether everyone's bundle is legit.
  8. ;    Ephraim Vishniac / P.O. Box 1357 / East Arlington, MA 02174
  9. ;    This program is in the public domain.
  10.  
  11. ;
  12.  
  13.     Include    Traps.D
  14.     Include    SysEquX.D
  15.     Include    FSEqu.D
  16.     Include    ToolEqu.D
  17.     Include    SysErr.D
  18.     Include    PackMacs.Txt
  19.  
  20. ;    Our Macros
  21.  
  22. MACRO    DoAlert        AlertNumber =
  23.     IF Debug
  24.     _Debugger
  25.     ENDIF
  26.     ; Alert (AlertNumber:INT, NIL:ProcPtr) : INT;
  27.     clr.w        -(sp)            ; space for result
  28.     move.w        #{AlertNumber},-(sp)    ; alert number
  29.     clr.l        -(sp)            ; NIL filter
  30.     _Alert
  31.     move.w        (sp)+,d0        ; d0 = button hit
  32.     cmp.w        #OKitem,d0        ; standard test
  33.     |
  34.  
  35. MACRO    DebugPoint =
  36.     IF Debug
  37.     _Debugger
  38.     ENDIF
  39.     |
  40.  
  41. MACRO    UseUs =
  42.     move.w        OurMap(a5),CurMap    ; make ours the current map
  43.     |
  44.  
  45. MACRO    UseThem =
  46.     move.w        TheirMap(a5),CurMap    ; make theirs the current map
  47.     |
  48.  
  49. MACRO    SetParamText =
  50.     move.l    ParamZero(a5),-(sp)    ; push our paramtext pointers
  51.     move.l    ParamOne(a5),-(sp)
  52.     move.l    ParamTwo(a5),-(sp)
  53.     move.l    ParamThree(a5),-(sp)
  54.     _ParamText
  55.     |
  56.  
  57. macro   DNAME   Name =
  58.         dc.b    '{Name|0:8}'
  59.     .align    2
  60.     |
  61.  
  62.  
  63. ;    Our alerts
  64.  
  65. Greeting    equ    128    ; say hello
  66. Farewell    equ    129    ; say goodbye
  67. SetVolFailed    equ    130    ; couldn't SetVol
  68. OpenResFailed    equ    131    ; couldn't OpenResFile
  69. BundleBitClear    equ    132    ; has bundles, but no bundle bit
  70. NumberOfTypes    equ    133    ; bundles has unusual number of types
  71. NoSigResource    equ    134    ; couldn't load signature resource
  72. NovelType    equ    135    ; neither ICN#, nor FREF
  73. MissingBundle    equ    136    ; bundle is too short
  74. ExcessBundle    equ    137    ; bundle runs too long
  75. FunnyIcon    equ    138    ; ICN# isn't 256 bytes
  76. SmallFREF    equ    139    ; FREF is less than six bytes
  77. BigFREF        equ    140    ; FREF is more than 262 bytes
  78. MissingResource    equ    141    ; can't find some bundled resource
  79. DoVolumeAlert    equ    142    ; should we do this volume?
  80. NoIcons        equ    143    ; no ICN# list in bundle
  81. NoFREFs        equ    144    ; no FREF list in bundle
  82. BadLocalID    equ    145    ; local ID unresolved
  83. OrphanType    equ    146    ; no FREF with this file type
  84. OrphanCreator    equ    147    ; no BNDL with matching signature
  85. BundleBitNoRF    equ    148    ; Bundle bit is on, but no resource fork
  86. BundleBitNoBNDL    equ    149    ; Bundle bit is on, but no bundles
  87. BlankImage    equ    150    ; The image area of the ICN# is blank
  88. BlankMask    equ    151    ; The mask area of the ICN# is blank
  89.  
  90. ;    Our dialogs
  91.  
  92. CurrentFile    equ    500
  93.  
  94. ;    Other miscellaneous equates
  95.  
  96. OKitem        equ    1    ; Item number for OK button
  97. QuitItem    equ    2    ; Item number for Quit button
  98.  
  99. ;    Our globals
  100.  
  101. OurMap        ds.w    1    ; a word from our sponsor
  102. TheirMap    ds.w    1    ; equal time for the other guy
  103. DialogPtr    ds.l    1    ; current dialog
  104. OtherBNDLs    ds.w    1    ; 'background count' of BNDL resources
  105. ParamZero    ds.l    1    ; our param zero text pointer
  106. ParamOne    ds.l    1    ; our param one text pointer
  107. ParamTwo    ds.l    1    ; our param two text pointer
  108. ParamThree    ds.l    1    ; our param three text pointer
  109. FileType    ds.l    1    ; File Type of current file
  110. FileCreator    ds.l    1    ; File Creator of current file
  111. TypeMatch    ds.b    1    ; flag for file type matched
  112. CreatorMatch    ds.b    1    ; flag for file creator matched
  113.  
  114.     XDef    FCensus
  115.  
  116. DeskCheck
  117. ;------------------------------- Init Managers ----------------------------
  118.  
  119.     pea    -4(A5)            ; Quickdraw's global area
  120.     _InitGraf            ; Init Quickdraw
  121.     _InitFonts            ; Init Font Manager
  122.     move.l    #$FFFF,D0        ; Flush all events
  123.     _FlushEvents
  124.     _InitWindows            ; Init Window Manager
  125.     _InitMenus            ; Init Menu Manager
  126.     _TEInit                ; Init Text Edit
  127.     clr.l    -(SP)            ; No restart procedure
  128.     _InitDialogs            ; Init Dialog Manager
  129.     _InitCursor            ; Turn on arrow cursor
  130.  
  131. ;------------------------------- Init Globals -----------------------------
  132.     move.w    CurMap,OurMap(a5)    ; record our resource refnum
  133.  
  134.     ; we need to discount bundles in our file and the system
  135.     clr.w    -(sp)
  136.     move.l    #'BNDL',-(sp)        ; How many bundles?
  137.     _CountResources
  138.     move.w    (sp)+,OtherBNDLs(a5)    ; save for later
  139.  
  140.     clr.l    ParamZero(a5)        ; clear our param text pointers
  141.     clr.l    ParamOne(a5)
  142.     clr.l    ParamTwo(a5)
  143.     clr.l    ParamThree(a5)
  144.  
  145. ;-------------------------------Desk Check---------------------------------
  146. ;    Just do a census of all files on all volumes, running them
  147. ;    through our bundle checker.
  148.  
  149.     DoAlert    Greeting        ; say hello
  150.     bne    SayByeBye        ; if not OK, split
  151.     
  152.     DebugPoint
  153.  
  154.     jsr    CheckAllVols        ; else test all volumes
  155.     DoAlert    FareWell        ; say goodbye
  156. SayByeBye
  157.     _ExitToShell
  158.  
  159.  
  160. ;    CheckAllVols: Check each mounted volume
  161.  
  162. CAVinfo        equ    -ioVQElSize    ; a handy parm block
  163. VolumeName    equ    CAVinfo-256    ; name of current volume
  164. LastLocal    set    VolumeName
  165.  
  166. CheckAllVols
  167.     link    a6,#LastLocal
  168.     lea    CAVinfo(a6),a0        ; a0 = parm block
  169.     clr.l    ioCompletion(a0)    ; no completion routine
  170.     lea    VolumeName(a6),a1    ; storage for volume name
  171.     move.l    a1,ioFileName(a0)    ; set in parm block
  172.     clr.w    ioVolIndex(a0)        ; clear index
  173. @0    lea    CAVinfo(a6),a0        ; a0 = parm block
  174.     clr.l    VolumeName(a6)        ; no volname yet
  175.     add.w    #1,ioVolIndex(a0)    ; advance to next volume
  176.     _GetVolInfo
  177.     cmp.w    #nsvErr,d0        ; out of volumes?
  178.     beq    @1            ; exit if so
  179.     move.l    ioFileName(a0),ParamZero(a5)    ; set param text zero
  180.     SetParamText
  181.     DoAlert    DoVolumeAlert        ; should we do this one?
  182.     bne    @0
  183.     lea    CAVinfo(a6),a0        ; a0 = parm block
  184.     jsr    CheckOneVol        ; else check this volume
  185.     bra    @0            ; and loop back
  186. @1    clr.l    ParamZero(a5)
  187.     unlk    a6
  188.     rts
  189.     DName    CHECKALLVOLS
  190.  
  191. ;    CheckOneVol: Survey a single volume
  192. ;    Entry:    a0 = _GetVolInfo poop on the volume to check
  193.  
  194. TheItemType    set    -2        ; Dialog item type
  195. TheItem        set    TheItemType-4    ; Dialog item handle
  196. TheBox        set    TheItem-8    ; Dialog item box
  197. LastLocal    set    TheBox
  198.  
  199. CheckOneVol
  200.     link    a6,#LastLocal
  201.     move.w    ioVRefNum(a0),-(sp)    ; save volume reference number
  202.     move.l    ioFileName(a0),-(sp)    ; save volume name pointer
  203.  
  204.     clr.l    -(sp)            ; space for result
  205.     move.w    #CurrentFile,-(sp)    ; dialog number
  206.     clr.l    -(sp)            ; take what we get
  207.     move.l    #-1,-(sp)        ; put this window in front
  208.     _GetNewDialog            ; Pop the question
  209.     move.l    (sp),DialogPtr(a5)    ; save the dialog pointer
  210.     _SetPort            ; make ours the current port
  211.     move.l    DialogPtr(a5),-(sp)
  212.     _DrawDialog            ; force complete dialog drawing
  213.  
  214.     move.l    DialogPtr(a5),-(sp)
  215.     move.w    #4,-(sp)        ; item number 4
  216.     pea    TheItemType(a6)        ; storage for item type
  217.     pea    TheItem(a6)        ; storage for item handle
  218.     pea    TheBox(a6)        ; storage for item box
  219.     _GetDItem
  220.     move.l    (sp)+,a1        ; file name pointer
  221.     move.l    TheItem(a6),-(sp)    ; item handle
  222.     move.l    a1,-(sp)        ; point to file name
  223.     _SetIText            ; set file name in dialog
  224.  
  225.     move.l    #2,-(sp)        ; root directory
  226.     pea    CheckOneFile        ; our file inspector
  227.     jsr    FCensus            ; scan everything
  228.  
  229.     move.l    DialogPtr(a5),-(sp)    ; push the dialog pointer
  230.     _DisposDialog            ; and kill the dialog
  231.  
  232.     unlk    a6
  233.     rts
  234.     DName    CHECKONEVOL
  235.  
  236. ;    CheckOneFile(ParamBlock:ParmBlkPtr; dirID:longint):boolean
  237. ;    Do the actual tests on a given file.
  238. ;    A6 offsets
  239. OldA6        set    0
  240. ReturnAddr    set    OldA6+4
  241. DirID        set    ReturnAddr+4    ; directory ID
  242. FileInfo    set    DirID+4        ; param block from _GetFileInfo
  243. ReturnValue    set    FileInfo+4    ; return value (0 = continue)
  244. ArgsSz        set    ReturnValue-DirID
  245. ;
  246. ParmBlk        set    OldA6-ioHVQElSize    ; local parm block
  247. ErrString    set    ParmBlk-32    ; Str31 for error codes
  248. TheItemType    set    ErrString-2    ; Dialog item type
  249. TheItem        set    TheItemType-4    ; Dialog item handle
  250. TheBox        set    TheItem-8    ; Dialog item box
  251. LastLocal    set    TheBox
  252.  
  253. CheckOneFile
  254.     link    a6,#LastLocal
  255.     clr.w    ReturnValue(a6)        ; always continue search
  256.     
  257.     move.l    DialogPtr(a5),-(sp)
  258.     move.w    #2,-(sp)        ; item number 2
  259.     pea    TheItemType(a6)        ; storage for item type
  260.     pea    TheItem(a6)        ; storage for item handle
  261.     pea    TheBox(a6)        ; storage for item box
  262.     _GetDItem
  263.     move.l    TheItem(a6),-(sp)    ; item handle
  264.     move.l    FileInfo(a6),a1        ; point to GetFileInfo stuff
  265.     move.l    ioFileName(a1),-(sp)    ; point to file name
  266.     _SetIText            ; set file name in dialog
  267.  
  268.     ; is there a resource fork?
  269.     move.l    FileInfo(a6),a1        ; point to _GetFileInfo stuff
  270.     tst.l    ioFlRLgLen(a1)        ; is there a resource fork?
  271.     bne    @8            ; skip if so
  272.  
  273.     ; There's no resource fork, so the bundle bit shouldn't be set.
  274.     move.l    FileInfo(a6),a1        ; point to _GetFileInfo stuff
  275.     move.w    ioFlUsrWds+fdFlags(a1),d0 ; d0 = file flags
  276.     btst    #fHasBundle,d0        ; test bundle bit
  277.     beq    @9            ; skip if clear, that makes sense
  278.  
  279.     ; This bozo has no resource fork, but the bundle bit is on
  280.     DoAlert    BundleBitNoRF
  281.     bra    @9
  282.  
  283. @8    lea    ParmBlk(a6),a0        ; point to parm block
  284.     clr.l    ioCompletion(a0)
  285.     clr.l    ioFileName(a0)
  286.     move.w    ioVRefNum(a1),ioVRefNum(a0) ; volume from file info
  287.     move.l    DirID(a6),ioWDDirID(a0)    ; directory ID from file info
  288.     tst    FSFCBLen        ; HFS running?
  289.     bmi    @0            ; branch if not
  290.     _HSetVol            ; HFS, set volume and directory
  291.     bra    @1
  292. @0    _SetVol                ; MFS, just set volume
  293. @1    move.w    ioResult(a0),d0        ; did it work?
  294.     beq    @2            ; skip if vol ok
  295.  
  296.     ext.l    d0
  297.     lea    ErrString(a6),a0
  298.     move.l    a0,ParamZero(a5)    ; move to param text ptrs
  299.     _NumToString
  300.     SetParamText
  301.     DoAlert    SetVolFailed
  302.     bra    @9
  303.  
  304. @2    move.l    FileInfo(a6),a1        ; point to _GetFileInfo stuff
  305.     clr.w    -(sp)            ; for _OpenResFile result
  306.     move.l    ioFileName(a1),-(sp)    ; push given file name
  307.     move.b    #0,ResLoad        ; don't load resources
  308.     _OpenResFile            ; give it a shot
  309.     move.b    #-1,ResLoad        ; do load resources
  310.     move.w    (sp)+,d0        ; pop reference number
  311.     bpl    @3            ; skip if reasonable number
  312.  
  313.     move.w    ResErr,d0        ; get the error code
  314.     ext.l    d0
  315.     lea    ErrString(a6),a0
  316.     move.l    a0,ParamZero(a5)    ; move to param text ptrs
  317.     _NumToString
  318.     SetParamText
  319.     UseUs                ; do we need this?
  320.     DoAlert    OpenResFailed
  321.     bra    @9
  322.  
  323.     ; While the other file is open, we have to bracket our
  324.     ; alerts and stuff with 'UseUs' - 'UseThem'
  325.  
  326. @3    cmp.w    SysMap,d0        ; did we just open the system?
  327.     beq    @9            ; skip ahead if so
  328.     cmp.w    OurMap(a5),d0        ; is it us?
  329.     beq    @9            ; skip ahead if so
  330.     move.w    d0,TheirMap(a5)        ; refnum of file under test
  331.  
  332.     ; Here's where we actually examine the file contents...
  333.  
  334.     ; Does this bozo have a bundle?
  335.     clr.w    -(sp)
  336.     move.l    #'BNDL',-(sp)        ; How many bundles?
  337.     _CountResources
  338.     move.w    (sp)+,d3        ; well?
  339.     cmp.w    OtherBNDLs(a5),d3    ; discount other bundles
  340.     bne    @7            ; skip if there are more, test them
  341.     
  342.     ; There are no bundles.  Is the bundle bit set anyway?
  343.     move.l    FileInfo(a6),a1        ; point to _GetFileInfo stuff
  344.     move.w    ioFlUsrWds+fdFlags(a1),d0 ; d0 = file flags
  345.     btst    #fHasBundle,d0        ; test bundle bit
  346.     beq    @5            ; skip if clear, that makes sense
  347.  
  348.     ; There are no bundles, but this bozo has his bundle bit set.
  349.     DoAlert    BundleBitNoBNDL
  350.     bra    @5
  351.  
  352. @7    move.l    FileInfo(a6),a1        ; point to _GetFileInfo stuff
  353.     move.l    ioFlUsrWds+fdType(a1),FileType(a5)    ; save file type
  354.     move.l    ioFlUsrWds+fdCreator(a1),FileCreator(a5) ; ditto creator
  355.     clr.b    TypeMatch(a5)        ; no matches yet
  356.     clr.b    CreatorMatch(a5)
  357.  
  358.     move.w    ioFlUsrWds+fdFlags(a1),d0 ; d0 = file flags
  359.     btst    #fHasBundle,d0        ; test bundle bit
  360.     bne    @4            ; skip if set, that makes sense
  361.  
  362.     move.w    D3,D0
  363.     sub.w    OtherBNDLs(a5),D0
  364.     ext.l    d0
  365.     lea    ErrString(a6),a0
  366.     move.l    a0,ParamZero(a5)    ; move to param text ptrs
  367.     _NumToString
  368.     SetParamText
  369.     UseUs
  370.     DoAlert    BundleBitClear
  371.     UseThem
  372.  
  373. @4    move.w    D3,D0            ; retrieve number of bundles
  374.     jsr    TestBundles        ; else go test the bundles
  375.     tst.b    TypeMatch(a5)        ; found FREF with our Type?
  376.     bne    @6            ; skip if so
  377.  
  378.     lea    ErrString+1(a6),a0    ; fudge alignment of string
  379.     move.l    a0,ParamZero(a5)    ; it's param text zero
  380.     move.b    #4,(a0)+        ; set string length
  381.     move.l    FileType(a5),(a0)    ; and string contents
  382.     SetParamText    
  383.     UseUs
  384.     DoAlert    OrphanType
  385.     UseThem
  386. @6    tst.b    CreatorMatch(a5)    ; found BNDL with our Creator?
  387.     bne    @5            ; skip if so
  388.  
  389.     lea    ErrString+1(a6),a0    ; fudge alignment of string
  390.     move.l    a0,ParamZero(a5)    ; it's param text zero
  391.     move.b    #4,(a0)+        ; set string length
  392.     move.l    FileCreator(a5),(a0)    ; and string contents
  393.     SetParamText    
  394.     UseUs
  395.     DoAlert    OrphanCreator
  396.     UseThem
  397.  
  398.     ; Here's where we close up the file
  399. @5    move.w    TheirMap(a5),-(sp)    ; retrieve test file refnum
  400.     _CloseResFile            ; and close it up
  401.  
  402.     move.w    CurMap,d0        ; check the current map
  403.     cmp.w    OurMap(a5),d0        ; is it us?
  404.     beq    @9            ; skip if so, we're good
  405.     DebugPoint
  406.  
  407.     ; so much for this file.  Restore default volume
  408. @9    UseUs                ; in case we opened the System...
  409.     clr.l    ParamZero(a5)        ; the string storage is gone
  410.     unlk    a6
  411.     move.l    (sp)+,a0        ; a0 = return address
  412.     lea    ArgsSz(sp),sp        ; pop arguments
  413.     jmp    (a0)            ; return
  414.     DName    CHECKONEFILE
  415.  
  416. ;    TestBundles: Test all the bundles of the current resource file
  417. ;    d0 = number of BNDL available
  418. ;    We only need to check ones native to the top map [TheirMap(a5)]
  419.  
  420. OldA6        set    0
  421. ReturnAddr    set    OldA6+4
  422.  
  423. ResIndex    set    OldA6-2        ; current resource index
  424. BNDLHandle    set    ResIndex-4    ; handle to current bundle
  425. LastLocal    set    BNDLHandle
  426.  
  427.  
  428. TestBundles
  429.     link    a6,#LastLocal
  430.     move.w    d0,ResIndex(a6)        ; resources to check
  431.  
  432. @0    clr.l    -(sp)
  433.     move.l    #'BNDL',-(sp)        ; resource type
  434.     move.w    ResIndex(a6),-(sp)    ; resource index
  435.     _GetIndResource            ; get the bundle
  436.     move.l    (sp)+,BNDLHandle(a6)    ; save handle
  437.     
  438.     ; is it one that we want?
  439.     clr.w    -(sp)
  440.     move.l    BNDLHandle(a6),-(sp)    ; current bundle
  441.     _HomeResFile
  442.     move.w    (sp)+,d0
  443.     cmp.w    TheirMap(a5),d0        ; is it theirs?
  444.     bne    @1            ; skip if not
  445.  
  446.     move.l    BNDLHandle(a6),a0    ; get the bundle handle
  447.     _HNoPurge            ; make it unpurgeable
  448.     move.l    BNDLHandle(a6),a0    ; get the bundle handle
  449.     _HLock                ; lock it down
  450.  
  451.     move.l    BNDLHandle(a6),a0    ; get the bundle handle
  452.     jsr    TestOneBundle        ; and check it out
  453.  
  454. @1    sub.w    #1,ResIndex(a6)        ; decrement resource index
  455.     bne    @0            ; and try again
  456.  
  457.     unlk    a6
  458.     rts
  459.     DName    TESTBUNDLES
  460.  
  461. ;    TestOneBundle: Examine one BNDL for validity, sanity, etc.
  462. ;    a0 = handle to the bundle
  463.  
  464. OldA6        set    0
  465. ReturnAddr    set    OldA6+4
  466.  
  467. BNDLHandle    set    OldA6-4        ; handle to current bundle
  468. BundleIDStr    set    BNDLHandle-32    ; Str31 for resource ID
  469. BundleSize    set    BundleIDStr-4    ; size of bundle
  470. BundleID    set    BundleSize-2    ; bundle's resource ID
  471. BundleType    set    BundleID-4    ; bundle's resource type
  472. BundleName    set    BundleType-256    ; bundle's resource name
  473. OtherString    set    BundleName-32    ; for other stuff
  474. ICNlist        set    OtherString-4    ; pointer to ICN# list
  475. FREFlist    set    ICNlist-4    ; pointer to FREF list
  476. LastLocal    set    FREFlist
  477.  
  478. TestOneBundle
  479.     link    a6,#LastLocal
  480.     movem.l    d2-d5/a2-a4,-(sp)    ; save some registers
  481.     clr.l    ICNlist(a6)        ; clear list pointers
  482.     clr.l    FREFlist(a6)
  483.  
  484.     move.l    a0,BNDLHandle(a6)    ; store bundle handle for later
  485.     move.l    (a0),a4            ; a4 = bundle pointer
  486.  
  487.     move.l    a0,-(sp)        ; push handle
  488.     pea    BundleID(a6)        ; pointer to resource ID var
  489.     pea    BundleType(a6)        ; pointer to resource type var
  490.     pea    BundleName(a6)        ; pointer to resource name var
  491.     _GetResInfo
  492.  
  493.     lea    BundleIDStr(a6),a0    ; string for bundle's res ID
  494.     move.l    a0,ParamZero(a5)    ; save for use in ParamText
  495.     move.w    BundleID(a6),d0        ; get the resource ID
  496.     ext.l    d0
  497.     _NumToString
  498.     SetParamText
  499.  
  500.     ; Examine the bundle for size-wise sanity
  501.     clr.l    -(sp)
  502.     move.l    BNDLHandle(a6),-(sp)
  503.     _SizeRsrc            ; how big is it?
  504.     move.l    (sp)+,D4        ; save for later
  505.     move.l    D4,BundleSize(a6)    ; might need original figure...
  506.     sub.w    #8,D4            ; at least minimum length?
  507.     bmi    @5            ; branch if not
  508.     move.l    (a4),D0            ; D0 = signature type
  509.     move.w    4(a4),d1        ; D1 = signature ID
  510.     jsr    TestSignature        ; check it out!
  511.  
  512.     move.w    6(a4),d3        ; D3 = # types - 1
  513.     cmp.w    #1,D3            ; usual number?
  514.     beq    @0            ; skip if so
  515.     move.w    d3,d0
  516.     add.w    #1,d0            ; actual number of types
  517.     lea    OtherString(a6),a0    ; other string
  518.     move.l    a0,ParamOne(a5)
  519.     ext.l    d0
  520.     _NumToString
  521.     SetParamText
  522.     UseUs
  523.     DoAlert    NumberOfTypes
  524.     UseThem
  525. @0    lea    8(a4),a4        ; a4 = header of first resource list
  526.  
  527. @1    sub.w    #6,D4            ; length of list header
  528.     bmi    @5            ; skip out if too short
  529.     cmpi.l    #'ICN#',(a4)        ; icons?
  530.     bne    @6            ; skip if not, try something else
  531.     move.l    a4,ICNlist(a6)        ; save ICN# list pointer
  532.     bra    @2            ; and go check the list
  533. @6    cmpi.l    #'FREF',(a4)        ; file references?
  534.     bne    @7            ; skip if not, it's something weird
  535.     move.l    a4,FREFlist(a6)        ; save FREF list pointer
  536.     bra    @2            ; and go check the list
  537. @7    lea    OtherString(a6),a0    ; point to other string
  538.     move.w    #4,(a0)
  539.     move.l    (a4),2(a0)        ; fill in resource type
  540.     lea    1(a0),a0        ; use odd-aligned string
  541.     move.l    a0,ParamOne(a5)
  542.     SetParamText
  543.     UseUs
  544.     DoAlert    NovelType
  545.     UseThem
  546. @2    move.w    4(a4),d2        ; resources - 1 of this type
  547.     lea    6(a4),a3        ; a3 = start of resource list
  548. @3    sub.w    #4,d4            ; size of list item
  549.     bmi    @5            ; skip out if too short
  550.     move.l    (a4),D0            ; resource type
  551.     move.w    2(a3),D1        ; resource ID
  552.     jsr    TestOneResource        ; test it!
  553.     lea    4(a3),a3        ; next item in list
  554.     dbra    d2,@3            ; collect them all
  555.     move.l    a3,a4            ; next list
  556.     dbra    d3,@1            ; collect all of those, too
  557.     tst.w    d4            ; All used up?
  558.     beq    @4            ; skip if so, that's just right
  559.     ; The bundle runs on longer than expected
  560.     UseUs
  561.     DoAlert    ExcessBundle
  562.     UseThem
  563. @4    move.l    ICNlist(a6),a0        ; pick up ICN# and FREF pointers
  564.     move.l    FREFlist(a6),a1
  565.     jsr    TestLocalIDs
  566.  
  567.     clr.l    ParamZero(a5)
  568.     clr.l    ParamOne(a5)
  569.     movem.l    (sp)+,d2-d5/a2-a4    ; restore some registers
  570.     unlk    a6
  571.     rts
  572.     DName    TESTONEBUNDLE
  573.  
  574. @5    UseUs
  575.     DoAlert    MissingBundle
  576.     UseThem
  577.     bra    @4
  578.  
  579.  
  580. ;    TestSignature: Does the 'signature' resource exist?
  581. ;    D0 = resource type
  582. ;    D1.w = resource ID
  583.  
  584. OldA6        set    0
  585. ReturnAddr    set    OldA6+4
  586.  
  587. SigType        set    OldA6-4        ; type of signature resource
  588. TypeStr        set    SigType-1    ; for type string
  589. FillerOne    set    TypeStr-1    ; restore alignment
  590. SigID        set    FillerOne-2    ; resource ID for signature
  591. IDString    set    SigID-32    ; Str31 for resource ID
  592.  
  593. LastLocal    set    IDString
  594.  
  595. TestSignature
  596.     link    a6,#LastLocal
  597.     move.l    d0,SigType(a6)        ; save signature's resource type
  598.     move.w    d1,SigID(a6)        ; save resource ID
  599.     cmp.l    FileCreator(a5),d0    ; FREF matches creator?
  600.     seq    d0
  601.     or.b    d0,CreatorMatch(a5)    ; set match flag if so
  602.  
  603.     clr.l    -(sp)
  604.     move.l    SigType(a6),-(sp)    ; resource type
  605.     move.w    SigID(a6),-(sp)        ; resource ID
  606.     _GetResource            ; Fetch!
  607.     move.l    (sp)+,d0        ; pop the handle
  608.     beq    @2            ; problem if NIL
  609.     tst.w    ResErr            ; something wrong?
  610.     bne    @2            ; skip if so
  611.     clr.w    -(sp)            ; check home file of resource
  612.     move.l    d0,-(sp)
  613.     _HomeResFile
  614.     move.w    (sp)+,d0        ; pop res file reference
  615.     cmp.w    TheirMap(a5),d0        ; right file?
  616.     beq    @0            ; branch if so, it's good
  617.  
  618. @2    move.b    #4,TypeStr(a6)        ; set resource type string
  619.     lea    TypeStr(a6),a0
  620.     move.l    a0,ParamOne(a5)
  621.     SetParamText
  622.  
  623.     move.w    SigID(a6),d0        ; d0 = signature's res ID
  624.     ext.l    d0
  625.     lea    IDString(a6),a0
  626.     move.l    a0,ParamTwo(a5)
  627.     _NumToString
  628.     SetParamText
  629.  
  630.     UseUs
  631.     DoAlert    NoSigResource
  632.     UseThem
  633.  
  634. @0    clr.l    ParamOne(a5)
  635.     clr.l    ParamTwo(a5)
  636.     unlk    a6
  637.     rts
  638.     DName    TESTSIGNATURE
  639.  
  640. ;    TestOneResource: Do a sanity check on one resource.
  641. ;        For all kinds, be sure it exists.
  642. ;        For ICN# and FREF, do some other stuff
  643. ;    D0 = resource type
  644. ;    D1.W = resource ID
  645.  
  646. OldA6        set    0
  647. ReturnAddr    set    OldA6+4
  648.  
  649. ResHandle    set    OldA6-4        ; handle to current resource
  650. ResType        set    ResHandle-4    ; resource type
  651. ResTypeStr    set    ResType-1    ; for using above as string
  652. FillerOne    set    ResTypeStr-1    ; restore alignment
  653. ResID        set    FillerOne-2    ; resource ID
  654. ResIDStr    set    ResID-32    ; Str31 for resource ID
  655. ResSize        set    ResIDStr-4    ; size of resource
  656. SizeString    set    ResSize-32    ; Str31 for resource size
  657. LastLocal    set    SizeString
  658.  
  659. TestOneResource
  660.     link    a6,#LastLocal
  661.     movem.l    d2-d5/a2-a4,-(sp)    ; save some registers
  662.  
  663.     move.l    d0,ResType(a6)
  664.     move.w    d1,ResID(a6)
  665.  
  666.     move.b    #4,ResTypeStr(a6)    ; build type string
  667.     lea    ResTypeStr(a6),a0
  668.     move.l    a0,ParamOne(a5)        ; set indirect pointer
  669.  
  670.     move.w    ResID(a6),d0        ; resource ID
  671.     lea    ResIDStr(a6),a0        ; ID string
  672.     move.l    a0,ParamTwo(a5)
  673.     ext.l    d0
  674.     _NumToString
  675.     SetParamText
  676.  
  677.     clr.l    -(sp)
  678.     move.l    ResType(a6),-(sp)    ; resource type
  679.     move.w    ResID(a6),-(sp)        ; resource ID
  680.     _GetResource            ; Fetch!
  681.     move.l    (sp)+,ResHandle(a6)    ; save the handle
  682.     tst.l    ResHandle(a6)        ; NIL handle?
  683.     beq    @4            ; error if so, resource is missing
  684.     tst.w    ResErr            ; something wrong?
  685.     bne    @4            ; skip if so
  686.     clr.w    -(sp)            ; else check home resource file
  687.     move.l    ResHandle(a6),-(sp)
  688.     _HomeResFile
  689.     move.w    (sp)+,d0        ; pop res file ref
  690.     cmp.w    TheirMap(a5),d0        ; right file?
  691.     beq    @0            ; branch if so, we'll take it
  692.  
  693. @4    UseUs
  694.     DoAlert    MissingResource
  695.     UseThem
  696.     bra    @9
  697. @0    clr.l    -(sp)
  698.     move.l    ResHandle(a6),-(sp)
  699.     _SizeRsrc            ; How big is this sucker?
  700.     move.l    (sp)+,ResSize(a6)    ; save for later testing
  701.  
  702.     move.l    ResSize(a6),d0        ; set up length string
  703.     lea    SizeString(a6),a0
  704.     move.l    a0,ParamThree(a5)
  705.     _NumToString
  706.     SetParamText
  707.  
  708.     move.l    ResType(a6),d0        ; d0 = resource type
  709.     cmpi.l    #'ICN#',d0        ; Icon list?
  710.     bne    @2            ; skip if not
  711.     
  712.     move.l    ResSize(a6),d0        ; check resource size
  713.     cmp.l    #256,d0            ; must be 256 bytes
  714.     beq    @5            ; skip if so, it's good
  715.     UseUs
  716.     DoAlert    FunnyIcon
  717.     UseThem
  718.  
  719. @5    move.l    ResHandle(a6),a0    ; a0 = ICN# handle
  720.     move.l    (a0),a0            ; a0 = ICN# pointer
  721.     clr.l    d0            ; accumulated OR of ICN# image
  722.     move.l    #31,d1            ; d1 = long words in ICN# image
  723. @6    or.l    (a0)+,d0        ; add up the ICN# image
  724.     dbra    d1,@6            ; loop through them all
  725.     tst.l    d0            ; is there some image?
  726.     bne    @7            ; jump if so, that's good
  727.     UseUs
  728.     DoAlert    BlankImage
  729.     UseThem
  730. @7    move.l    ResHandle(a6),a0    ; a0 = ICN# handle
  731.     move.l    (a0),a0            ; a0 = ICN# pointer
  732.     lea    128(a0),a0        ; a0 = ICN# mask pointer
  733.     clr.l    d0            ; accumulated OR of ICN# mask
  734.     move.l    #31,d1            ; d1 = long words in ICN# mask
  735. @8    or.l    (a0)+,d0        ; add up the ICN# mask
  736.     dbra    d1,@8            ; loop through them all
  737.     tst.l    d0            ; is there some mask?
  738.     bne    @9            ; jump if so, that's good
  739.     UseUs
  740.     DoAlert    BlankMask
  741.     UseThem
  742.     bra    @9
  743.     
  744. @2    cmpi.l    #'FREF',d0        ; FREF?
  745.     bne    @9            ; exit if not, we don't care
  746.     move.l    ResSize(a6),d0        ; check resource size
  747.     cmpi.l    #6,d0            ; reasonable size?
  748.     bcc    @3            ; branch if minimum or more
  749.     UseUs
  750.     DoAlert    SmallFREF        ; the FREF is too small
  751.     UseThem
  752.     bra    @9
  753. @3    cmpi.l    #263,d0            ; not too big?
  754.     bcs    @9            ; branch if in bounds
  755.     UseUs
  756.     DoAlert    BigFREF
  757.     UseThem
  758.  
  759. @9    clr.l    ParamOne(a5)
  760.     clr.l    ParamTwo(a5)
  761.     clr.l    ParamThree(a5)
  762.     movem.l    (sp)+,d2-d5/a2-a4    ; restore some registers
  763.     unlk    a6
  764.     rts
  765.     DName    TESTONERESOURCE
  766.  
  767. ;    TestLocalIDs: See if the local IDs referred to by the FREFs are
  768. ;            resolved in the ICN# list.
  769. ;    a0 = ptr to ICN# list from bundle
  770. ;    a1 = ptr to FREF list from bundle
  771.  
  772. FREFIDStr    set    -32        ; Str31 for FREF ID #
  773. LocalIDStr    set    FREFIDStr-32    ; Str31 for local ID #
  774. FREFHandle    set    LocalIDStr-4    ; handle of current FREF
  775. LastLocal    set    FREFHandle
  776.  
  777. TestLocalIDs
  778.     link    a6,#LastLocal        ; some local storage
  779.     movem.l    a2-a4/d2-d4,-(sp)    ; save some regs
  780.     
  781.     move.l    a0,d0            ; is there an ICN# list?
  782.     bne    @0            ; skip if so
  783.     UseUs
  784.     DoAlert    NoIcons
  785.     UseThem
  786.     bra    @9
  787. @0    move.l    a1,d0            ; is there an FREF list?
  788.     bne    @1            ; skip if so
  789.     UseUs
  790.     DoAlert    NoFREFs
  791.     UseThem
  792.     bra    @9
  793. @1    move.l    a0,a4            ; a4 = ICN# list pointer
  794.     move.w    4(a1),d4        ; d4 = # FREFs - 1
  795.     lea    6(a1),a3        ; a3 = first FREF item
  796. @2    clr.l    -(sp)
  797.     move.l    #'FREF',-(sp)
  798.     move.w    2(a3),-(sp)
  799.     _GetResource            ; get the FREF
  800.     move.l    (sp)+,d0        ; pop the handle
  801.     beq    @5            ; skip if NIL handle
  802.     tst.w    ResErr
  803.     bne    @5            ; skip if resource error
  804.     move.l    d0,FREFHandle(a6)    ; save FREF handle
  805.     clr.w    -(sp)            ; check home res file
  806.     move.l    d0,-(sp)
  807.     _HomeResFile
  808.     move.w    (sp)+,d0        ; pop home res file
  809.     cmp.w    TheirMap(a5),d0        ; from a good home?
  810.     bne    @5            ; exit if not
  811.  
  812.     move.l    FREFHandle(a6),a0    ; a0 = FREF handle
  813.     move.l    (a0),a0            ; a0 = FREF pointer
  814.  
  815.     move.l    (a0),d0            ; d0 = file type from FREF
  816.     cmp.l    FileType(a5),d0        ; match our file type?
  817.     seq    d0
  818.     or.b    d0,TypeMatch(a5)    ; set type match flag if so
  819.  
  820.     move.w    4(a0),d0        ; d0 = local ID from FREF
  821.     move.w    4(a4),d3        ; d3 = # ICN#s - 1
  822.     lea    6(a4),a2        ; a2 = first ICN# item
  823. @3    cmp.w    (a2),d0            ; local IDs match?
  824.     beq    @5            ; skip if so, test next FREF
  825.     lea    4(a2),a2        ; else move to next ICN# item
  826.     dbra    d3,@3            ; search through ICN# list
  827.  
  828.     ; If we fall out, we have an unsatisfied local ID in d0
  829.  
  830.     ext.l    d0
  831.     lea    LocalIDStr(a6),a0    ; string for local resource ID
  832.     move.l    a0,ParamTwo(a5)
  833.     _NumToString
  834.     move.w    2(a3),d0        ; FREF resource ID
  835.     ext.l    d0
  836.     lea    FREFIDStr(a6),a0    ; string for FREF resource ID
  837.     move.l    a0,ParamOne(a5)
  838.     _NumToString
  839.     SetParamText
  840.     UseUs
  841.     DoAlert    BadLocalID
  842.     UseThem
  843.     clr.l    ParamOne(a5)
  844.     clr.l    ParamTwo(a5)
  845. @5    lea    4(a3),a3        ; next FREF item in list
  846.     dbra    d4,@2            ; test entire FREF list
  847. @9    movem.l    (sp)+,a2-a4/d2-d4    ; restore registers
  848.     unlk    a6
  849.     rts
  850.     DName    TESTLOCALIDS
  851.  
  852.