home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Workbench / dosdrivers / HAPPYENV.LHA / HappyENV-Handler.asm < prev    next >
Encoding:
Assembly Source File  |  1996-10-28  |  40.7 KB  |  2,092 lines

  1. *************************
  2. *   HappyENV-Handler    *
  3. *     0.9 27.10.96    *
  4. *  (C) Martin Gierich    *
  5. *************************
  6.  
  7.  
  8. ; Do not use this source code or parts of it in other programs !
  9. ; See documentation about Copyright&Disclaimer
  10.  
  11.  
  12.  
  13. DEBUG        = 1
  14. VOLUME        = 1
  15. VERBOSE        = 1
  16. AUTOCOPY    = 1
  17. ;EXPAND        = 1
  18.  
  19.     INCDIR    source:stripinc/
  20.     INCLUDE    exec/exec_lib.i
  21.     INCLUDE    dos/dos_lib.i
  22.     INCLUDE    dos/dosextens.i
  23.     INCLUDE    dos/filehandler.i
  24.     INCLUDE    dos/notify.i
  25.     INCLUDE debug.i
  26.  
  27. CALL    MACRO
  28.     jsr    _LVO\1(a6)
  29.     ENDM
  30.  
  31. mn_Node        = 0
  32. lib_Version    = 20
  33. _LVOToUpper    = -174
  34. DOS_TRUE    = -1
  35. DOS_FALSE    = 0
  36. MEMF_CLEAR    = $10000
  37. MAXPATH        = 120
  38. MAXNAME        = 32
  39. BLOCKSIZE    = 5000
  40.  
  41.  
  42. * notify list node structure
  43.         RSRESET
  44. myn_Link    RS.L    1
  45. myn_Request    RS.L    1    notify-request
  46. myn_Key        RS.L    1    pointer to file
  47. myn_Name    RS.B    0    path/file name (dynamic)
  48.  
  49. * lock structure for Lock() and open files
  50.         RSRESET
  51. myl_Link    RS.L    1
  52. myl_Key        RS.L    1
  53. myl_Access    RS.L    1
  54. myl_Task    RS.L    1
  55. myl_Volume    RS.L    1
  56. myl_Pos        RS.L    1    position in file (read/write)
  57. myl_Data    RS.L    1    start of file data (read)
  58. myl_Start    RS.L    1    start of block list (write)
  59. myl_Block    RS.L    1    current block (write)
  60. myl_BlockPos    RS.L    1    position in current block (write)
  61. myl_Size    RS.L    1    size of file
  62. myl_Mode    RS.B    1    0=simple lock, -1=write, 1=read
  63. myl_Pad        RS.B    1
  64. myl_SIZEOF    RS.W    0
  65.  
  66. * structure for file or dir
  67.         RSRESET
  68. myf_Link    RS.L    1    next file/dir
  69. myf_Parent    RS.L    1    parent dir (root: 0)
  70. myf_First    RS.L    0    dir:  points to first entry
  71. myf_Size    RS.L    1    file: size of filedata
  72. myf_Type    RS.B    1    bit7: dir/file, 6:hidden, 5:copied,
  73.             ;    4:notify
  74. myf_Locks    RS.B    1    number of locks, -1=write lock
  75. myf_DataOffs    RS.B    1    offset to start of data
  76. myf_Name    RS.W    0    name (dynamic), then data
  77.  
  78. * private main structure
  79.         RSRESET
  80. CharTable    RS.B    256
  81. DosBase        RS.L    1
  82. MyProcess    RS.L    1
  83. MyMsgPort    RS.L    1
  84. MyMemPool    RS.L    1
  85. MyDeviceNode    RS.L    1
  86. MyVolumeBPTR    RS.L    1
  87. NotifyList    RS.L    1
  88. Copyfrom    RS.L    1
  89. CopyfromLock    RS.L    1
  90. CopyfromPort    RS.L    1
  91. RootLock    RS.L    1
  92. StartDate    RS.B    ds_SIZEOF
  93. MyPacket    RS.B    sp_SIZEOF
  94. VolumeNode    RS.B    DevList_SIZEOF
  95. VolumeName    RS.B    MAXNAME
  96. NotifyPort    RS.B    MP_SIZE
  97. PacketPort    RS.B    MP_SIZE
  98. FileSize    RS.L    1
  99. TotalSize    RS.L    1
  100. NumLocks    RS.L    1
  101. Kickver        RS.W    1
  102. WriteProtected    RS.B    1
  103. NSignal        RS.B    1
  104. PSignal        RS.B    1
  105. Paddy1        RS.B    1
  106. RootDir        RS.B    myf_Name+8
  107. Paddy2        RS.B    3
  108. TempPath    RS.B    MAXPATH
  109. TempName    RS.B    MAXNAME
  110. My_SIZEOF    RS.W    0
  111.  
  112. MyPkt        = MyPacket+sp_Pkt
  113.  
  114. *******************************************************
  115.  
  116. *******************************************************
  117.  
  118. ;a4=DOSpacket
  119. ;a5=private struct
  120. ;a6=execbase
  121. start:    movem.l    d2-d7/a2-a6,-(sp)    do some basic inits
  122.     move.l    4.w,a6
  123.     move.l    #My_SIZEOF,d0
  124.     move.l    #MEMF_CLEAR!1,d1
  125.     CALL    AllocMem
  126.     tst.l    d0
  127.     beq    exit1
  128.     move.l    d0,a5
  129.     DBUG1    txstart,a5
  130.     lea    dosname(pc),a1
  131.     moveq    #33,d0
  132.     CALL    OpenLibrary
  133.     move.l    d0,DosBase(a5)
  134.     beq    exit2
  135.     move.l    d0,a2
  136.     CALL    Forbid
  137.     move.l    dl_Root(a2),a0
  138.     lea    rn_Time(a0),a0
  139.     lea    StartDate(a5),a1
  140.     move.l    (a0)+,(a1)+
  141.     move.l    (a0)+,(a1)+
  142.     move.l    (a0),(a1)
  143.     CALL    Permit
  144.     move.w    lib_Version(a6),Kickver(a5)
  145.     sub.l    a1,a1
  146.     CALL    FindTask
  147.     move.l    d0,MyProcess(a5)
  148.     cmp.w    #36,Kickver(a5)
  149.     blo.s    .OS13
  150.     move.l    d0,a0
  151.     bset    #0,pr_Flags+3(a0)
  152. .OS13    add.l    #pr_MsgPort,d0
  153.     move.l    d0,MyMsgPort(a5)
  154. ;    clr.b    RootDir+myf_Type(a5)
  155.     cmp.w    #39,Kickver(a5)
  156.     blo.s    .OS20
  157.     moveq    #1,d0
  158.     move.l    #5000,d1
  159.     move.l    #2000,d2
  160.     CALL    CreatePool
  161.     move.l    d0,MyMemPool(a5)
  162.  
  163. .OS20    move.l    MyMsgPort(a5),a2    process startup message
  164.     bsr    GetPacket
  165.     move.l    d0,a4
  166.     move.l    dp_Arg3(a4),d0
  167.     lsl.l    #2,d0
  168.     move.l    d0,MyDeviceNode(a5)
  169.     move.l    d0,a0
  170.     move.l    MyMsgPort(a5),dn_Task(a0)
  171.     clr.l    dn_SegList(a0)
  172.     move.l    dn_Name(a0),a0
  173.     lea    RootDir+myf_Name(a5),a1
  174.     moveq    #6,d0
  175.     bsr    CopyBSTR2Char
  176.     moveq    #DOS_TRUE,d0
  177.     move.l    d0,dp_Res1(a4)
  178.     bsr    ReplyPacket
  179.  
  180.     lea    VolumeNode(a5),a2    set up volume node
  181.     move.l    a2,d0
  182.     lsr.l    #2,d0
  183.     move.l    d0,MyVolumeBPTR(a5)
  184.     moveq    #2,d0
  185.     move.l    d0,dl_Type(a2)
  186.     move.l    MyMsgPort(a5),dl_Task(a2)
  187.     move.l    #"DOS"<<8,dl_DiskType(a2)
  188.     lea    volname(pc),a0
  189.     lea    VolumeName(a5),a1
  190.     moveq    #MAXNAME-2,d0
  191.     bsr    CopyChar2BSTR
  192.     move.l    d0,dl_Name(a2)
  193.     IFD    VOLUME
  194.     move.l    DosBase(a5),a0
  195.     move.l    dl_Root(a0),a0
  196.     move.l    rn_Info(a0),a0
  197.     add.l    a0,a0
  198.     add.l    a0,a0
  199.     move.l    di_DevInfo(a0),d0
  200.     move.l    d0,VolumeNode(a5)
  201.     move.l    MyVolumeBPTR(a5),di_DevInfo(a0)
  202.     ENDC
  203.  
  204.     bsr    InitConversion        init upper case table
  205.     lea    NotifyPort(a5),a2    create msgport for notify
  206.     move.b    #NT_MSGPORT,LN_TYPE(a2)
  207.     moveq    #-1,d0
  208.     CALL    AllocSignal
  209.     tst.l    d0
  210.     bmi    exit3
  211.     move.b    d0,NSignal(a5)
  212.     move.b    d0,MP_SIGBIT(a2)
  213.     move.l    MyProcess(a5),MP_SIGTASK(a2)
  214.     lea    MP_MSGLIST(a2),a0
  215.     move.b    #NT_MESSAGE,LH_TYPE(a0)
  216.     NEWLIST    a0
  217.     lea    PacketPort(a5),a2    create msgport for DOSpackets
  218.     move.b    #NT_MSGPORT,LN_TYPE(a2)
  219.     moveq    #-1,d0
  220.     CALL    AllocSignal
  221.     tst.l    d0
  222.     bmi    exit3
  223.     move.b    d0,PSignal(a5)
  224.     move.b    d0,MP_SIGBIT(a2)
  225.     move.l    MyProcess(a5),MP_SIGTASK(a2)
  226.     lea    MP_MSGLIST(a2),a0
  227.     move.b    #NT_MESSAGE,LH_TYPE(a0)
  228.     NEWLIST    a0
  229.     lea    RootDir(a5),a2        create Lock for DiskInfo
  230.     moveq    #ACCESS_READ,d2
  231.     bsr    CreateLock
  232.     move.l    d0,RootLock(a5)
  233.     beq    exit4
  234.  
  235.     IFD    AUTOCOPY
  236.     CALL    Forbid
  237.     move.l    DosBase(a5),a0
  238.     move.l    dl_Root(a0),a0
  239.     move.l    rn_Info(a0),a0
  240.     add.l    a0,a0
  241.     add.l    a0,a0
  242.     lea    di_DevInfo(a0),a2
  243. .C    move.l    (a2),d0
  244.     beq.s    .D
  245.     lsl.l    #2,d0
  246.     move.l    d0,a2
  247.     move.l    dol_Name(a2),a0
  248.     add.l    a0,a0
  249.     add.l    a0,a0
  250.     lea    sysdisk(pc),a1
  251.     moveq    #0,d0
  252.     move.b    (a0)+,d0
  253.     bra.s    .F
  254. .G    move.b    (a1)+,d1
  255.     cmp.b    (a0)+,d1
  256.     bne.s    .C
  257. .F    dbra    d0,.G
  258.     tst.b    (a1)
  259.     bne.s    .C
  260.     CALL    Permit
  261.     move.l    a2,Copyfrom(a5)
  262.     DBUG1    txcopy,Copyfrom(a5)
  263.     bra.s    .A
  264. .D    CALL    Permit
  265. .A    ENDC
  266.  
  267. loop    move.l    MyMsgPort(a5),a2    enter main loop
  268.     bsr    GetPacket
  269.     move.l    d0,a4
  270.     bsr    GetNotify
  271.     clr.l    dp_Res1(a4)
  272.     clr.l    dp_Res2(a4)
  273.     move.l    dp_Type(a4),d0
  274.     IFD    DEBUG
  275.     move.l    dp_Port(a4),a1
  276.     move.l    MP_SIGTASK(a1),a1
  277.     move.l    LN_NAME(a1),a1
  278.     DBUG5    txpack,d0,dp_Arg1(a4),dp_Arg2(a4),dp_Arg3(a4),a1
  279.     ENDC
  280.     move.l    d0,d1
  281.     swap    d1
  282.     tst.w    d1
  283.     bne.s    .A
  284.     lea    start(pc),a1
  285.     lea    JumpTable(pc),a2
  286.     moveq    #0,d2
  287. .C    move.w    (a2)+,d1
  288.     bpl.s    .E
  289. .A    DBUG1    txerr1,d0
  290.     move.w    #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
  291.     bra.s    .D
  292. .E    move.w    (a2)+,d2
  293.     cmp.w    d0,d1
  294.     bne.s    .C
  295.     add.l    d2,a1
  296.     jsr    (a1)
  297. .D    IFD    DEBUG
  298.     moveq    #DOS_TRUE,d0
  299.     cmp.l    dp_Res1(a4),d0
  300.     beq.s    .H
  301.     DBUG2    txres,dp_Res1(a4),dp_Res2(a4)
  302. .H    ENDC
  303.     bsr    ReplyPacket
  304.     bra    loop
  305.  
  306. AExit    addq.l    #4,sp        exit routine
  307.     moveq    #DOS_TRUE,d0
  308.     move.l    d0,dp_Res1(a4)
  309.     bsr    ReplyPacket
  310.     IFND    DEBUG
  311.     move.l    NumLocks(a5),d0
  312.     subq.l    #1,d0
  313.     bne    loop
  314.     ENDC
  315.     move.l    RootLock(a5),a1
  316.     bsr    FreeLock
  317. exit4    move.l    MyDeviceNode(a5),a0
  318.     clr.l    dn_Task(a0)
  319.     bsr    FlushPackets
  320.     IFD    VOLUME
  321.     move.l    DosBase(a5),a0
  322.     move.l    dl_Root(a0),a0
  323.     move.l    rn_Info(a0),a0
  324.     add.l    a0,a0
  325.     add.l    a0,a0
  326.     move.l    VolumeNode(a5),d0
  327.     move.l    d0,di_DevInfo(a0)
  328.     ENDC
  329.  
  330.     moveq    #0,d0
  331.     move.b    PSignal(a5),d0
  332.     CALL    FreeSignal
  333.     moveq    #0,d0
  334.     move.b    NSignal(a5),d0
  335.     CALL    FreeSignal
  336. exit3    move.l    DosBase(a5),a1
  337.     CALL    CloseLibrary
  338. exit2    move.l    MyDeviceNode(a5),a0
  339.     clr.l    dn_Task(a0)
  340.     DBUG2    txend,FileSize(a5),TotalSize(a5)
  341.     move.l    MyMemPool(a5),d0
  342.     beq.s    .A
  343.     move.l    d0,a0
  344.     CALL    DeletePool
  345. .A    move.l    a5,a1
  346.     move.l    #My_SIZEOF,d0
  347.     CALL    FreeMem
  348. exit1    movem.l    (sp)+,d2-d7/a2-a6
  349.     moveq    #0,d0
  350.     rts
  351.  
  352. *******************************************************
  353.  
  354. JumpTable:
  355.     dc.w    ACTION_NIL,NoAction-start
  356. ;    dc.w    ACTION_SET_PROTECT,NoAction-start
  357. ;    dc.w    ACTION_SET_COMMENT,NoAction-start
  358. ;    dc.w    ACTION_SET_DATE,NoAction-start
  359.     dc.w    ACTION_FLUSH,NoAction-start
  360.     dc.w    ACTION_IS_FILESYSTEM,NoAction-start
  361.  
  362.     dc.w    ACTION_DIE,AExit-start
  363.     dc.w    ACTION_CURRENT_VOLUME,ACurrentVolume-start
  364.     dc.w    ACTION_RENAME_DISK,ARenameDisk-start
  365.     dc.w    ACTION_WRITE_PROTECT,AWriteProtect-start
  366.  
  367.     dc.w    ACTION_FINDUPDATE,AOpenNewfile-start
  368.     dc.w    ACTION_FINDINPUT,AOpenOldfile-start
  369.     dc.w    ACTION_FINDOUTPUT,AOpenNewfile-start
  370.     dc.w    ACTION_END,ACloseFile-start
  371.     dc.w    ACTION_SEEK,ASeekPosition-start
  372.     dc.w    ACTION_READ,AReadFile-start
  373.     dc.w    ACTION_WRITE,AWriteFile-start
  374.     dc.w    ACTION_DELETE_OBJECT,ADeleteObject-start
  375.     dc.w    ACTION_RENAME_OBJECT,ARenameObject-start
  376.     dc.w    ACTION_CREATE_DIR,ACreateDir-start
  377.  
  378.     dc.w    ACTION_LOCATE_OBJECT,ALocateObject-start
  379.     dc.w    ACTION_PARENT,AParentDir-start
  380.     dc.w    ACTION_COPY_DIR,ADuplicateLock-start
  381.     dc.w    ACTION_FREE_LOCK,AFreeLock-start
  382.     dc.w    ACTION_SAME_LOCK,ASameLock-start
  383.     dc.w    ACTION_EXAMINE_OBJECT,AExamineObject-start
  384.     dc.w    ACTION_EXAMINE_FH,AExamineFH-start
  385.     dc.w    ACTION_EXAMINE_NEXT,AExamineNext-start
  386.     dc.w    ACTION_DISK_INFO,ADiskInfo1-start
  387.     dc.w    ACTION_INFO,ADiskInfo2-start
  388.  
  389.     dc.w    ACTION_ADD_NOTIFY,AAddNotify-start
  390.     dc.w    ACTION_REMOVE_NOTIFY,ARemoveNotify-start
  391.     dc.w    ACTION_SET_FILE_SIZE,ASetFileSize-start
  392.     dc.w    ACTION_FH_FROM_LOCK,AFHfromLock-start
  393. ;    dc.w    ACTION_CHANGE_MODE,AChangeMode-start
  394.     dc.w    ACTION_COPY_DIR_FH,ADupLockFromFH-start
  395.     dc.w    ACTION_PARENT_FH,AParentFromFH-start
  396.     dc.w    -1
  397.  
  398.         IFD    VOLUME
  399. volname        dc.b    "Environment",0
  400.         ENDC
  401.         IFND    VOLUME
  402. volname        dc.b    "Env",0
  403.         ENDC
  404.         IFD    EXPAND
  405. prefstx        dc.b    "prefs",0
  406. configtx    dc.b    "config",0
  407.         ENDC
  408. version        dc.b    "$VER: HappyENV-Handler 0.9 (27.10.96)",10,0
  409. dosname        dc.b    "dos.library",0
  410. utilname    dc.b    "utility.library",0
  411. sysdisk        dc.b    "ENVARC",0
  412.         even
  413.  
  414. *******************************************************
  415.  
  416. * Init to-upper-conversion table
  417. InitConversion:
  418.     lea    CharTable(a5),a2
  419.     move.w    #255,d0
  420. .A    move.b    d0,0(a2,d0.w)
  421.     dbra    d0,.A
  422.     moveq    #"A",d0
  423. .C    move.b    d0,"a"-"A"(a2,d0.w)
  424.     addq.w    #1,d0
  425.     cmp.b    #"Z"+1,d0
  426.     bne.s    .C
  427.     move.w    #192,d0
  428. .F    move.b    d0,224-192(a2,d0.w)
  429.     addq.w    #1,d0
  430.     cmp.b    #222+1,d0
  431.     bne.s    .F
  432.  
  433.     lea    utilname(pc),a1    open utility.library
  434.     moveq    #37,d0
  435.     CALL    OpenLibrary
  436.     tst.l    d0
  437.     beq.s    .D
  438.     move.l    d0,a6
  439.     move.w    #255,d2
  440. .E    move.w    d2,d0
  441.     CALL    ToUpper
  442.     move.b    d0,0(a2,d2.w)
  443.     dbra    d2,.E
  444.     move.l    a6,a1
  445.     move.l    4.w,a6
  446.     CALL    CloseLibrary
  447. .D    rts
  448.  
  449.  
  450. * Wait for a packet, then get it
  451. * ENTRY: a2=msgport
  452. * EXIT:  d0=packet
  453. GetPacket:
  454. .A    move.l    a2,a0
  455.     CALL    WaitPort
  456.     move.l    a2,a0
  457.     CALL    GetMsg
  458.     tst.l    d0
  459.     beq.s    .A
  460.     move.l    d0,a0
  461.     move.l    mn_Node+LN_NAME(a0),d0
  462.     beq.s    .A
  463.     rts
  464.  
  465. * Reply packet in a4
  466. ReplyPacket:
  467.     move.l    a4,a2
  468.     move.l    dp_Port(a4),a0        reply port
  469.     move.l    MyMsgPort(a5),dp_Port(a2)
  470. * ENTRY: a2=packet to send, a0=msgport to send to
  471. SendPacket:
  472.     move.l    dp_Link(a2),a1        message to send
  473.     move.l    a2,mn_Node+LN_NAME(a1)
  474.     clr.l    mn_Node+LN_SUCC(a1)
  475.     clr.l    mn_Node+LN_PRED(a1)
  476.     move.b    #NT_MESSAGE,mn_Node+LN_TYPE(a1)
  477.     CALL    PutMsg
  478.     rts
  479.  
  480. FlushPackets:
  481. .A    move.l    MyMsgPort(a5),a0
  482.     CALL    GetMsg
  483.     tst.l    d0
  484.     beq.s    .C
  485.     move.l    d0,a0
  486.     move.l    mn_Node+LN_NAME(a0),d0
  487.     beq.s    .A
  488.     move.l    d0,a4
  489.     clr.l    dp_Res1(a4)
  490.     move.w    #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
  491.     bsr    ReplyPacket
  492.     bra.s    .A
  493. .C    rts
  494.  
  495. * Send a packet to the handler in CopyfromPort and wait for a reply
  496. * ENTRY: d0=dp_Type, d1=dp_Arg1, d2=dp_Arg2, d3=dp_Arg3
  497. * EXIT:  d0=dp_Res1, d1=dp_Res2, Z-flag
  498. DoPacket:
  499.     move.l    a2,-(sp)
  500.     lea    MyPacket(a5),a1
  501.     lea    sp_Pkt(a1),a2
  502.     move.l    a1,dp_Link(a2)
  503.     lea    PacketPort(a5),a1
  504.     move.l    a1,dp_Port(a2)
  505.     move.l    d0,dp_Type(a2)
  506.     move.l    d1,dp_Arg1(a2)
  507.     move.l    d2,dp_Arg2(a2)
  508.     move.l    d3,dp_Arg3(a2)
  509.     move.l    CopyfromPort(a5),a0
  510.     bsr    SendPacket
  511.     lea    PacketPort(a5),a2
  512.     bsr    GetPacket
  513.     move.l    d0,a0
  514.     DBUG4    txpkt,a0,dp_Type(a0),dp_Res1(a0),dp_Res2(a0)
  515. ;    bsr    wait_c
  516.     move.l    dp_Res2(a0),d1
  517.     move.l    dp_Res1(a0),d0
  518.     move.l    (sp)+,a2
  519.     rts
  520.  
  521. *******************************************************
  522.  
  523. *******************************************************
  524.  
  525. NoAction:
  526.     moveq    #DOS_TRUE,d0
  527.     move.l    d0,dp_Res1(a4)
  528.     rts
  529.  
  530. ACurrentVolume:
  531.     move.l    MyVolumeBPTR(a5),dp_Res1(a4)
  532.     rts
  533.  
  534. ARenameDisk:
  535.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  536.     tst.b    WriteProtected(a5)
  537.     bne.s    .fail
  538.     move.l    dp_Arg1(a4),a0
  539.     lea    TempName(a5),a1
  540.     moveq    #MAXNAME-2,d0
  541.     bsr    CopyBSTR2Char
  542.     lea    TempName(a5),a0
  543.     lea    VolumeName(a5),a1
  544.     moveq    #MAXNAME-2,d0
  545.     bsr    CopyChar2BSTR
  546.     moveq    #DOS_TRUE,d0
  547.     move.l    d0,dp_Res1(a4)
  548. .fail    rts
  549.  
  550. AWriteProtect:
  551.     move.l    dp_Arg1(a4),d0
  552.     move.b    d0,WriteProtected(a5)
  553.     moveq    #DOS_TRUE,d0
  554.     move.l    d0,dp_Res1(a4)
  555.     rts    
  556.  
  557. AOpenOldfile:
  558.     move.l    dp_Arg3(a4),a0
  559.     move.l    dp_Arg2(a4),d0
  560.     moveq    #ACCESS_READ,d2
  561.     bsr    LocateObject
  562. OpnOld:    move.l    dp_Arg1(a4),a3
  563.     add.l    a3,a3
  564.     add.l    a3,a3
  565.     clr.l    fh_Interactive(a3)
  566.     move.l    d0,fh_Arg1(a3)
  567.     beq.s    .fail
  568.     move.l    d0,a0
  569.     move.l    myl_Key(a0),a1
  570.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  571.     tst.b    myf_Type(a1)    do not open dirs
  572.     bmi.s    .A
  573.     move.l    a0,a1
  574.     bsr    FreeLock
  575.     bra.s    .fail
  576. .A    clr.l    myl_Pos(a0)
  577.     move.l    myf_Size(a1),myl_Size(a0)
  578.     moveq    #0,d0
  579.     move.b    myf_DataOffs(a1),d0
  580.     add.l    d0,a1
  581.     move.l    a1,myl_Data(a0)
  582.     clr.l    myl_Start(a0)
  583.     clr.l    myl_Block(a0)
  584.     clr.l    myl_BlockPos(a0)
  585.     move.b    #1,myl_Mode(a0)
  586.     moveq    #DOS_TRUE,d0
  587.     move.l    d0,dp_Res1(a4)
  588.     DBUG1    txopeno,fh_Arg1(a3)
  589. .fail    rts
  590.  
  591. AOpenNewfile:
  592.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  593.     tst.b    WriteProtected(a5)
  594.     bne    .fail
  595.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  596.     move.l    dp_Arg1(a4),a3
  597.     add.l    a3,a3
  598.     add.l    a3,a3
  599.     clr.l    fh_Interactive(a3)
  600.     move.l    dp_Arg2(a4),d0    does file already exist ?
  601.     move.l    dp_Arg3(a4),a0
  602.     bsr    DelSearchObject
  603.     beq.s    .A
  604.     move.l    d0,a1
  605.     tst.b    myf_Type(a1)    do not overwrite dirs
  606.     bpl    .fail
  607.     bsr    DeleteObject
  608.     beq    .fail
  609. .A    bsr    SplitPath
  610.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  611.     move.l    dp_Arg2(a4),d0
  612.     bsr    CreatePath
  613.     beq    .fail
  614.     move.l    a3,-(sp)
  615.     move.l    d0,a3
  616.     lea    TempName(a5),a2
  617.     moveq    #0,d2
  618.     bsr    CreateNewObject
  619.     move.l    (sp)+,a3
  620.     beq.s    .fail
  621.     move.l    d0,a2
  622.     moveq    #ACCESS_WRITE,d2
  623.     bsr    CreateLock
  624.     move.l    d0,fh_Arg1(a3)
  625.     beq.s    .fail
  626.     move.l    d0,a0
  627.     move.b    #-1,myl_Mode(a0)
  628.     clr.l    myl_Pos(a0)
  629.     clr.l    myl_Data(a0)
  630.     clr.l    myl_Start(a0)
  631.     clr.l    myl_Block(a0)
  632.     clr.l    myl_BlockPos(a0)
  633.     clr.l    myl_Size(a0)
  634.     moveq    #DOS_TRUE,d0
  635.     move.l    d0,dp_Res1(a4)
  636.     DBUG1    txopenn,fh_Arg1(a3)
  637. .fail    rts
  638.  
  639. ACloseFile:
  640.     move.l    dp_Arg1(a4),a1
  641.     cmp.b    #-1,myl_Mode(a1)
  642.     beq.s    .D
  643.     bsr    FreeLock
  644.     bra.s    .ok
  645. .D    move.l    myl_Size(a1),d2
  646.     move.l    myl_Key(a1),a2
  647.     move.l    myf_Parent(a2),a3
  648.     lea    myf_Name(a2),a2
  649.     bsr    CreateNewObject
  650.     beq.s    .fail
  651.     move.l    d0,d4
  652.     move.l    d0,a3
  653.     add.l    d1,a3
  654.     move.l    dp_Arg1(a4),a2
  655.     move.l    myl_Start(a2),d3
  656. .F    tst.l    d3
  657.     beq.s    .A
  658.     move.l    d3,-(sp)
  659.     move.l    d3,a0
  660.     move.l    (a0)+,d3
  661.     move.l    (a0)+,d2
  662.     move.l    a3,a1
  663.     move.l    d2,d0
  664.     CALL    CopyMem
  665.     add.l    d2,a3
  666.     move.l    d2,d0
  667.     addq.l    #8,d0
  668.     move.l    (sp)+,a1
  669.     bsr    FreeMem
  670.     bra.s    .F
  671. .A    move.l    a2,a1
  672.     move.l    myl_Key(a2),a2
  673.     bsr    FreeLock
  674.     move.l    a2,a1
  675.     bsr    DeleteObj
  676.     beq.s    .fail
  677.     move.l    d4,a0
  678.     bsr    CheckNotify
  679. .ok    moveq    #DOS_TRUE,d0
  680.     move.l    d0,dp_Res1(a4)
  681. .fail    rts
  682.  
  683. AWriteFile:
  684.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  685.     tst.b    WriteProtected(a5)
  686.     bne    .fail
  687.     moveq    #-1,d0
  688.     move.l    d0,dp_Res1(a4)
  689.     move.l    dp_Arg1(a4),a2    lock
  690.     move.l    dp_Arg2(a4),a3    buffer
  691.     move.l    dp_Arg3(a4),d3    length
  692.     move.w    #ERROR_WRITE_PROTECTED,dp_Res2+2(a4)
  693.     cmp.b    #-1,myl_Mode(a2)
  694.     bne    .fail
  695. .F    move.l    d3,d2
  696.     move.l    myl_Block(a2),d0
  697.     beq    .E
  698.     move.l    d0,a1
  699.     move.l    4(a1),d0
  700.     sub.l    myl_BlockPos(a2),d0
  701.     beq.s    .C
  702.     bmi.s    .C
  703.     cmp.l    d2,d0
  704.     bhs.s    .D
  705.     move.l    d0,d2
  706. .D    addq.l    #8,a1
  707.     add.l    myl_BlockPos(a2),a1
  708.     move.l    a3,a0
  709.     move.l    d2,d0
  710.     CALL    CopyMem
  711.     DBUG2    txwins,d2,myl_Pos(a2)
  712.     add.l    d2,a3
  713.     add.l    d2,myl_Pos(a2)
  714.     add.l    d2,myl_BlockPos(a2)
  715.     sub.l    d2,d3
  716.     beq.s    .ok
  717.     bra.s    .F
  718. .C    move.l    (a1),d0
  719.     beq.s    .E
  720.     move.l    d0,myl_Block(a2)
  721.     clr.l    myl_BlockPos(a2)
  722.     bra    .F    
  723.     
  724. .E    move.w    #ERROR_DISK_FULL,dp_Res2+2(a4)
  725.     move.l    d3,d0
  726.     addq.l    #8,d0
  727.     bsr    AllocMem
  728.     beq    .fail
  729.     move.l    myl_Block(a2),a0
  730.     move.l    d0,myl_Block(a2)
  731.     move.l    a0,d1
  732.     bne.s    .A
  733.     lea    myl_Start(a2),a0
  734. .A    move.l    d0,(a0)
  735.  
  736.     move.l    d3,d2
  737.     move.l    d0,a1
  738.     clr.l    (a1)+
  739.     move.l    d2,(a1)+
  740.     move.l    a3,a0
  741.     move.l    d2,d0
  742.     CALL    CopyMem
  743.     add.l    d2,myl_Size(a2)
  744.     add.l    d2,myl_Pos(a2)
  745.     move.l    d2,myl_BlockPos(a2)
  746. .ok    move.l    dp_Arg3(a4),dp_Res1(a4)
  747.     clr.w    dp_Res2+2(a4)
  748.     DBUG3    txwrite,dp_Arg3(a4),myl_Pos(a2),myl_Size(a2)
  749. .fail    rts
  750.  
  751. AReadFile:
  752.     moveq    #-1,d0
  753.     move.l    d0,dp_Res1(a4)
  754.     move.l    dp_Arg1(a4),a2
  755.     move.w    #ERROR_READ_PROTECTED,dp_Res2+2(a4)
  756.     cmp.b    #1,myl_Mode(a2)
  757.     bne.s    .fail
  758.     move.l    myl_Size(a2),d0
  759.     move.l    myl_Pos(a2),a0
  760.     sub.l    a0,d0
  761.     move.l    dp_Arg3(a4),d2
  762.     cmp.l    d0,d2
  763.     bls.s    .A
  764.     exg.l    d0,d2
  765. .A    move.l    myl_Data(a2),d0
  766.     add.l    d0,a0
  767.     move.l    dp_Arg2(a4),a1
  768.     move.l    d2,d0
  769.     CALL    CopyMem
  770.     add.l    d2,myl_Pos(a2)
  771.     move.l    d2,dp_Res1(a4)
  772.     clr.w    dp_Res2+2(a4)
  773.     DBUG3    txread,d2,dp_Arg3(a4),myl_Pos(a2)
  774. .fail    rts
  775.  
  776. ASeekPosition
  777.     move.l    dp_Arg1(a4),a2
  778.     move.l    dp_Arg2(a4),d1    position
  779.     move.l    dp_Arg3(a4),d2    mode
  780.     clr.w    dp_Res2+2(a4)
  781.     move.l    myl_Pos(a2),d3
  782.     move.l    myl_Size(a2),d4
  783.  
  784.     moveq    #OFFSET_BEGINNING,d0
  785.     cmp.l    d0,d2
  786.     beq.s    .E
  787.     moveq    #OFFSET_END,d0
  788.     cmp.l    d0,d2
  789.     bne.s    .C
  790.     add.l    d4,d1
  791.     bra.s    .E
  792. .C    moveq    #OFFSET_CURRENT,d0
  793.     cmp.l    d0,d2
  794.     bne.s    .fail
  795.     add.l    d3,d1
  796. .E    move.l    d1,myl_Pos(a2)
  797.     bmi.s    .A
  798.     cmp.l    d1,d4
  799.     bhs.s    Seeek
  800.     move.l    d4,myl_Pos(a2)
  801.     bra.s    .fail
  802. .A    clr.l    myl_Pos(a2)
  803. .fail    move.w    #ERROR_SEEK_ERROR,dp_Res2+2(a4)
  804.     moveq    #-1,d3
  805.  
  806. Seeek    cmp.b    #-1,myl_Mode(a2)
  807.     bne.s    .A
  808.     move.l    myl_Pos(a2),d2
  809.     move.l    myl_Start(a2),d0
  810.     beq.s    .A
  811.     bra.s    .E
  812. .D    move.l    (a0),d0
  813.     beq.s    .C
  814. .E    move.l    d0,a0
  815.     move.l    4(a0),d1
  816.     sub.l    d1,d2
  817.     beq.s    .F
  818.     bpl.s    .D
  819. .F    add.l    d1,d2
  820. .C    move.l    a0,myl_Block(a2)
  821.     move.l    d2,myl_BlockPos(a2)
  822. .A    move.l    d3,dp_Res1(a4)
  823.     DBUG1    txseek,myl_Pos(a2)
  824.     rts
  825.  
  826. ADeleteObject:
  827.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  828.     tst.b    WriteProtected(a5)
  829.     bne.s    .fail
  830.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  831.     move.l    dp_Arg1(a4),d0
  832.     move.l    dp_Arg2(a4),a0
  833.     bsr    SearchObject
  834.     beq.s    .fail
  835.     movem.l    d0-d1,-(sp)
  836.     move.l    d0,a0
  837.     moveq    #1,d0
  838.     bsr    NotifyObject
  839.     movem.l    (sp)+,d0-d1
  840.     move.l    d0,a1
  841.     bsr    DeleteObject
  842.     beq.s    .fail
  843.     moveq    #DOS_TRUE,d0
  844.     move.l    d0,dp_Res1(a4)
  845. .fail    rts
  846.  
  847. ARenameObject:
  848.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  849.     tst.b    WriteProtected(a5)
  850.     bne    .fail
  851.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  852.     move.l    dp_Arg1(a4),d0
  853.     move.l    dp_Arg2(a4),a0
  854.     bsr    SearchObject
  855.     beq    .fail
  856.     move.l    d0,a3
  857.     move.l    d1,d3
  858.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  859.     tst.b    myf_Locks(a3)
  860.     bne    .fail
  861.     move.l    a3,a0
  862.     bsr    NotifyObject
  863.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  864.     move.l    dp_Arg3(a4),d0
  865.     move.l    dp_Arg4(a4),a0
  866.     bsr    DelSearchObject
  867.     bne    .fail
  868.     bsr    SplitPath
  869.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  870.     move.l    dp_Arg3(a4),d0
  871.     bsr    SearchPath
  872.     beq    .fail
  873.     move.l    a3,-(sp)
  874.     moveq    #0,d2
  875.     tst.b    myf_Type(a3)
  876.     bpl.s    .D
  877.     move.l    myf_Size(a3),d2
  878. .D    move.l    d0,a3
  879.     lea    TempName(a5),a2
  880.     bsr    CreateNewObject
  881.     move.l    (sp)+,a3
  882.     beq.s    .fail
  883.     move.l    d0,a2
  884.     move.b    myf_Type(a3),myf_Type(a2)
  885.     bpl.s    .A
  886.     move.l    a2,a1        rename file
  887.     add.l    d1,a1
  888.     move.l    a3,a0
  889.     moveq    #0,d0
  890.     move.b    myf_DataOffs(a3),d0
  891.     add.l    d0,a0
  892.     move.l    myf_Size(a3),d0
  893.     CALL    CopyMem
  894.     bra.s    .C
  895. .A    move.l    myf_First(a3),d0    rename dir
  896.     clr.l    myf_First(a3)
  897.     move.l    d0,myf_First(a2)
  898.     beq.s    .C
  899. .E    move.l    d0,a0
  900.     move.l    a2,myf_Parent(a0)
  901.     move.l    myf_Link(a0),d0
  902.     bne.s    .E
  903. .C    move.l    d3,d1        end rename
  904.     move.l    a3,a1
  905.     bsr    DeleteObject
  906.     beq.s    .fail
  907.     move.l    a2,a0
  908.     bsr    CheckNotify
  909.     moveq    #DOS_TRUE,d0
  910.     move.l    d0,dp_Res1(a4)
  911. .fail    rts
  912.  
  913. *******************************************************
  914.  
  915. ALocateObject:
  916.     move.l    dp_Arg1(a4),d0
  917.     move.l    dp_Arg2(a4),a0
  918.     move.l    dp_Arg3(a4),d2
  919.     bsr    LocateObject
  920.     lsr.l    #2,d0
  921.     move.l    d0,dp_Res1(a4)
  922.     rts
  923.  
  924. ADupLockFromFH:
  925.     move.l    dp_Arg1(a4),d0
  926.     bra.s    DupLock
  927.  
  928. ADuplicateLock:
  929.     move.l    dp_Arg1(a4),d0
  930.     lsl.l    #2,d0
  931. DupLock    beq.s    .fail
  932.     move.l    d0,a0
  933.     move.l    myl_Key(a0),a2
  934.     moveq    #ACCESS_READ,d2
  935.     bsr    CreateLock
  936.     lsr.l    #2,d0
  937.     move.l    d0,dp_Res1(a4)
  938. .fail    rts
  939.  
  940. AParentFromFH:
  941.     move.l    dp_Arg1(a4),d0
  942.     bra.s    ParentD
  943. AParentDir:
  944.     move.l    dp_Arg1(a4),d0
  945.     lsl.l    #2,d0
  946. ParentD    beq.s    .fail
  947.     move.l    d0,a0
  948.     move.l    myl_Key(a0),a2
  949.     move.l    myf_Parent(a2),d0
  950.     beq.s    .fail
  951.     move.l    d0,a2
  952.     moveq    #ACCESS_READ,d2
  953.     bsr    CreateLock
  954.     lsr.l    #2,d0
  955.     move.l    d0,dp_Res1(a4)
  956. .fail    rts
  957.  
  958. AFreeLock:
  959.     move.l    dp_Arg1(a4),d0
  960.     beq.s    .fail
  961.     lsl.l    #2,d0
  962.     move.l    d0,a1
  963.     bsr    FreeLock
  964.     moveq    #DOS_TRUE,d0
  965.     move.l    d0,dp_Res1(a4)
  966. .fail    rts
  967.  
  968. ASameLock:
  969.     moveq    #LOCK_SAME_VOLUME,d0
  970.     move.l    d0,dp_Res1(a4)
  971.     move.l    dp_Arg1(a4),a0
  972.     add.l    a0,a0
  973.     add.l    a0,a0
  974.     move.l    dp_Arg2(a4),a1
  975.     add.l    a1,a1
  976.     add.l    a1,a1
  977.     move.l    myl_Key(a0),d0
  978.     cmp.l    myl_Key(a1),d0
  979.     bne.s    .A
  980.     moveq    #LOCK_SAME,d0
  981.     move.l    d0,dp_Res1(a4)
  982. .A    rts
  983.  
  984. AExamineFH:
  985.     move.l    dp_Arg1(a4),a0
  986.     bra.s    Exami
  987.  
  988. AExamineObject:
  989.     move.l    dp_Arg1(a4),a0
  990.     add.l    a0,a0
  991.     add.l    a0,a0
  992. Exami    move.l    myl_Key(a0),a0
  993.     move.l    dp_Arg2(a4),a1
  994.     add.l    a1,a1
  995.     add.l    a1,a1
  996.     DBUG1    txexam,a0
  997.     move.l    a1,a2
  998.     moveq    #fib_SIZEOF/4-1,d0
  999. .D    clr.l    (a2)+
  1000.     dbra    d0,.D
  1001. * ENTRY: a0=file, a1=fib
  1002. ExamineObject:
  1003.     moveq    #1,d0
  1004.     tst.l    myf_Parent(a0)
  1005.     beq.s    .C        rootdir ?
  1006.     IFD    DEBUG
  1007.     btst    #6,myf_Type(a0)
  1008.     beq.s    .D        hidden file ?
  1009.     moveq    #-5,d0
  1010.     bra.s    .C
  1011. .D    ENDC
  1012.     moveq    #-3,d0
  1013.     tst.b    myf_Type(a0)
  1014.     bmi.s    .C        file ?
  1015.     moveq    #2,d0        dir
  1016. .C    moveq    #0,d1
  1017.     move.l    d0,fib_DirEntryType(a1)
  1018.     move.l    d0,fib_EntryType(a1)
  1019.     bpl.s    .A
  1020.     move.l    myf_Size(a0),d1        no file no size
  1021. .A    move.l    a0,fib_DiskKey(a1)
  1022.     move.l    d1,fib_Size(a1)        calc size
  1023.     add.l    #1023,d1
  1024.     lsr.l    #8,d1
  1025.     lsr.l    #2,d1
  1026.     move.l    d1,fib_NumBlocks(a1)
  1027.     moveq    #2,d0
  1028.     move.b    myf_Type(a0),d1
  1029.     btst    #5,d1        copied ? -> A
  1030.     beq.s    .F
  1031.     bset    #4,d0
  1032. .F    btst    #4,d1        notify ? -> P
  1033.     beq.s    .G
  1034.     bset    #5,d0
  1035. .G    move.l    d0,fib_Protection(a1)
  1036.     move.l    StartDate+0(a5),fib_DateStamp+0(a1)
  1037.     move.l    StartDate+4(a5),fib_DateStamp+4(a1)
  1038.     move.l    StartDate+8(a5),fib_DateStamp+8(a1)
  1039.     lea    myf_Name(a0),a0
  1040.     lea    fib_FileName(a1),a1
  1041.     moveq    #106,d0
  1042.     bsr    CopyChar2BSTR
  1043.     moveq    #DOS_TRUE,d0
  1044.     move.l    d0,dp_Res1(a4)
  1045.     rts
  1046.  
  1047. AExamineNext:
  1048.     move.l    dp_Arg1(a4),a2
  1049.     add.l    a2,a2
  1050.     add.l    a2,a2
  1051.     move.l    dp_Arg2(a4),a1
  1052.     add.l    a1,a1
  1053.     add.l    a1,a1
  1054.     move.l    fib_DiskKey(a1),a0
  1055.     DBUG1    txexnx,a0
  1056.     cmp.l    myl_Key(a2),a0
  1057.     bne.s    .A
  1058.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1059.     tst.b    myf_Type(a0)
  1060.     bmi.s    .fail
  1061.     move.l    myf_First-myf_Link(a0),a0
  1062.     bra.s    .C
  1063. .A    move.l    myf_Link(a0),a0
  1064. .C    move.w    #ERROR_NO_MORE_ENTRIES,dp_Res2+2(a4)
  1065.     move.l    a0,d0
  1066.     beq.s    .fail
  1067.     IFND    DEBUG
  1068.     btst    #6,myf_Type(a0)
  1069.     bne.s    .A
  1070.     ENDC
  1071.     bra    ExamineObject
  1072. .fail    rts
  1073.  
  1074. ADiskInfo1:
  1075.     move.l    dp_Arg1(a4),a0
  1076.     bra.s    DiskInfo
  1077. ADiskInfo2:
  1078.     move.l    dp_Arg2(a4),a0
  1079. DiskInfo:
  1080.     add.l    a0,a0
  1081.     add.l    a0,a0
  1082.     move.l    a0,a1
  1083.     moveq    #id_SIZEOF/4-1,d0
  1084. .D    clr.l    (a1)+
  1085.     dbra    d0,.D
  1086.     IFD    DEBUG
  1087.     move.l    NumLocks(a5),id_NumSoftErrors(a0)
  1088.     ENDC
  1089.     moveq    #ID_VALIDATED,d0
  1090.     tst.b    WriteProtected(a5)
  1091.     beq.s    .C
  1092.     moveq    #ID_WRITE_PROTECTED,d0
  1093. .C    move.l    d0,id_DiskState(a0)
  1094.     move.l    #1024,d1
  1095.     move.l    d1,id_BytesPerBlock(a0)
  1096.     lsr.l    #1,d1
  1097.     move.l    FileSize(a5),d0
  1098.     add.l    d1,d0
  1099.     lsr.l    #8,d0
  1100.     lsr.l    #2,d0
  1101.     move.l    d0,id_NumBlocksUsed(a0)
  1102.     move.l    TotalSize(a5),d0
  1103.     add.l    d1,d0
  1104.     lsr.l    #8,d0
  1105.     lsr.l    #2,d0
  1106.     bne.s    .A
  1107.     moveq    #1,d0
  1108. .A    move.l    d0,id_NumBlocks(a0)
  1109.     move.l    #"DOS"<<8,id_DiskType(a0)
  1110.     move.l    MyVolumeBPTR(a5),id_VolumeNode(a0)
  1111.     move.l    RootLock(a5),id_InUse(a0)
  1112.     moveq    #DOS_TRUE,d0
  1113.     move.l    d0,dp_Res1(a4)
  1114.     rts
  1115.  
  1116. ACreateDir:
  1117.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  1118.     tst.b    WriteProtected(a5)
  1119.     bne.s    .fail
  1120.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  1121.     move.l    dp_Arg1(a4),d0
  1122.     move.l    dp_Arg2(a4),a0
  1123.     bsr    DelSearchObject
  1124.     bne.s    .fail
  1125.     bsr    SplitPath
  1126.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  1127.     move.l    dp_Arg1(a4),d0
  1128.     bsr    CreatePath
  1129.     beq.s    .fail
  1130.     move.l    d0,a3
  1131.     lea    TempName(a5),a2
  1132.     moveq    #0,d2
  1133.     bsr    CreateNewObject
  1134.     beq.s    .fail
  1135.     move.l    d0,a2
  1136.     clr.b    myf_Type(a2)
  1137.     moveq    #ACCESS_WRITE,d2
  1138.     bsr    CreateLock
  1139.     beq.s    .fail
  1140.     move.l    d0,a0
  1141.     lsr.l    #2,d0
  1142.     move.l    d0,dp_Res1(a4)
  1143.     move.l    myl_Key(a0),a0
  1144.     bsr    CheckNotify
  1145. .fail    rts
  1146.  
  1147. *******************************************************
  1148.  
  1149. ASetFileSize:
  1150.     move.l    dp_Arg1(a4),a2
  1151.     move.l    myl_Size(a2),dp_Res1(a4)
  1152.     rts
  1153.  
  1154. AFHfromLock:
  1155.     move.w    #ERROR_WRITE_PROTECTED,dp_Res2+2(a4)
  1156.     move.l    dp_Arg2(a4),d0
  1157.     beq.s    .fail
  1158.     lsl.l    #2,d0
  1159.     move.l    d0,a0
  1160.     moveq    #ACCESS_READ,d1    read access supported only
  1161.     cmp.l    myl_Access(a0),d1
  1162.     bne.s    .fail
  1163.     move.l    myl_Key(a0),a0
  1164.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1165.     tst.b    myf_Type(a0)    do not open dirs
  1166.     bmi    OpnOld
  1167. .fail    rts
  1168.  
  1169. AChangeMode:
  1170.     rts
  1171.  
  1172. *******************************************************
  1173.  
  1174. AAddNotify:
  1175.     move.w    #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
  1176.     move.l    dp_Arg1(a4),a3
  1177.     moveq    #myn_Name,d0
  1178.     move.l    nr_FullName(a3),a0
  1179. .C    addq.l    #1,d0
  1180.     tst.b    (a0)+
  1181.     bne.s    .C
  1182.     bsr    AllocMem
  1183.     beq.s    .fail
  1184.     move.l    d0,a2
  1185.     lea    NotifyList(a5),a0
  1186.     move.l    (a0),myn_Link(a2)
  1187.     move.l    a2,(a0)
  1188.     move.l    a3,myn_Request(a2)
  1189.     move.l    nr_FullName(a3),a0
  1190.     lea    myn_Name(a2),a1
  1191. .D    move.b    (a0)+,(a1)+
  1192.     bne.s    .D
  1193.     bsr    UpNoti
  1194.     IFD    DEBUG
  1195.     lea    myn_Name(a2),a0
  1196.     DBUG4    txanoti,a2,a3,a0,d0
  1197.     ENDC
  1198.     move.l    nr_Flags(a3),d1
  1199.     btst    #NRB_NOTIFY_INITIAL,d1    initial notify ?
  1200.     beq.s    .A
  1201.     tst.l    d0
  1202.     beq.s    .A
  1203.     move.l    d0,a0
  1204.     btst    #6,myf_Type(a0)        file really exists ?
  1205.     bne.s    .A
  1206.     bsr    SendNotify
  1207. .A    moveq    #DOS_TRUE,d0
  1208.     move.l    d0,dp_Res1(a4)
  1209. .fail    rts
  1210.  
  1211. ARemoveNotify:
  1212.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1213.     move.l    dp_Arg1(a4),a2
  1214.     tst.l    nr_MsgCount(a2)
  1215.     bne.s    .fail
  1216.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1217.     lea    NotifyList(a5),a1
  1218. .A    move.l    (a1),d0
  1219.     beq.s    .fail
  1220.     move.l    a1,a0
  1221.     move.l    d0,a1
  1222.     cmp.l    myn_Request(a1),a2
  1223.     bne.s    .A
  1224.     move.l    myn_Link(a1),myn_Link(a0)
  1225.     DBUG2    txrnoti,a1,a2
  1226.     move.l    myn_Key(a1),d0
  1227.     beq.s    .D
  1228.     move.l    d0,a0
  1229.     bclr    #4,myf_Type(a0)
  1230. .D    moveq    #myn_Name,d0
  1231.     lea    myn_Name(a1),a0
  1232. .C    addq.l    #1,d0
  1233.     tst.b    (a0)+
  1234.     bne.s    .C
  1235.     bsr    FreeMem
  1236.     moveq    #DOS_TRUE,d0
  1237.     move.l    d0,dp_Res1(a4)
  1238. .fail    rts
  1239.  
  1240. * Update myn_Key of notification list and do notify
  1241. * ENTRY: a0=file
  1242. UpdateNotify:
  1243.     move.l    a2,-(sp)
  1244.     lea    NotifyList(a5),a2
  1245.     bra.s    .A
  1246. .C    move.l    d0,a2
  1247.     tst.l    myn_Key(a2)
  1248.     bne.s    .A
  1249.     bsr.s    UpNoti
  1250.     IFD    DEBUG
  1251.     beq.s    .A
  1252.     lea    myn_Name(a2),a0
  1253.     DBUG2    txunoti,a0,d0
  1254.     ENDC
  1255. .A    move.l    (a2),d0
  1256.     bne.s    .C
  1257.     move.l    (sp)+,a2
  1258.     rts
  1259.  
  1260. * Subroutine used by UpdateNotify and AddNotify
  1261. UpNoti    lea    myn_Name(a2),a0
  1262.     lea    TempPath(a5),a1
  1263.     moveq    #MAXPATH-1,d0
  1264.     bsr    CopyChar2Char
  1265.     moveq    #0,d0
  1266.     bsr    SearchPath
  1267.     bne.s    .A
  1268.     moveq    #0,d0
  1269.     bsr    CalcFullName
  1270. .A    move.l    d0,myn_Key(a2)
  1271.     beq.s    .D
  1272.     move.l    d0,a0
  1273.     bset    #4,myf_Type(a0)
  1274. .D    rts
  1275.  
  1276. * Check notification list for file/dir and parent dir and notify it.
  1277. * ENTRY: a0=file
  1278. CheckNotify:
  1279.     move.l    a0,-(sp)
  1280.     IFD    DEBUG
  1281.     lea    myf_Name(a0),a0
  1282.     DBUG1    txcnoti,a0
  1283.     ENDC
  1284.     bsr    UpdateNotify
  1285.     move.l    (sp)+,a0
  1286. NotifyObject:
  1287.     bsr    NotifyObj
  1288.     move.l    myf_Parent(a0),d1
  1289.     move.l    d1,a0
  1290.     beq.s    .E
  1291.     bsr    NotifyObj
  1292. .E    rts
  1293.  
  1294. NotifyObj:
  1295.     movem.l    a2/a3,-(sp)
  1296.     lea    NotifyList(a5),a2
  1297.     bra.s    .A
  1298. .C    move.l    d0,a2
  1299.     cmp.l    myn_Key(a2),a0
  1300.     bne.s    .A
  1301.     move.l    a0,-(sp)
  1302.     move.l    myn_Request(a2),a3
  1303.     bsr    SendNotify
  1304.     move.l    (sp)+,a0
  1305. .A    move.l    (a2),d0
  1306.     bne.s    .C
  1307.     movem.l    (sp)+,a2/a3
  1308.     rts
  1309.  
  1310. * Send a Notify message or set a Notify signal
  1311. * ENTRY: a3=NotifyRequest
  1312. SendNotify:
  1313.     btst    #NRB_SEND_SIGNAL,nr_Flags+3(a3)
  1314.     beq.s    .C
  1315.     move.l    nr_Task(a3),a1
  1316.     IFD    DEBUG
  1317.     move.l    LN_NAME(a1),d0
  1318.     lea    myn_Name(a2),a0
  1319.     DBUG2    txsnoti,d0,a0
  1320.     ENDC
  1321.     moveq    #0,d0
  1322.     move.b    nr_SignalNum(a3),d1
  1323.     bset    d1,d0
  1324.     CALL    Signal
  1325.     rts
  1326.  
  1327. .C    btst    #NRB_SEND_MESSAGE,nr_Flags+3(a3)
  1328.     beq    .D
  1329.     moveq    #NotifyMessage_SIZEOF,d0
  1330.     bsr    AllocMem
  1331.     beq    .D
  1332.     move.l    d0,a0
  1333.     move.l    d0,a1
  1334.     moveq    #NotifyMessage_SIZEOF/2-1,d0
  1335. .A    clr.w    (a0)+
  1336.     dbra    d0,.A
  1337.     move.b    #NT_MESSAGE,LN_TYPE(a1)
  1338.     lea    NotifyPort(a5),a0
  1339.     move.l    a0,MN_REPLYPORT(a1)
  1340.     move.w    #NotifyMessage_SIZEOF,MN_LENGTH(a1)
  1341.     move.l    #$40000000,nm_Class(a1)
  1342.     move.w    #$1234,nm_Code(a1)
  1343.     move.l    a3,nm_NReq(a1)
  1344.     IFD    DEBUG
  1345.     move.l    a2,-(sp)
  1346.     move.l    nr_Port(a3),a0
  1347.     move.l    MP_SIGTASK(a0),a0
  1348.     move.l    LN_NAME(a0),a0
  1349.     lea    myn_Name(a2),a2
  1350.     DBUG3    txmnoti,a1,a0,a2
  1351.     move.l    (sp)+,a2
  1352.     ENDC
  1353.     move.l    nr_Port(a3),a0
  1354.     CALL    PutMsg
  1355.     addq.l    #1,nr_MsgCount(a3)
  1356. ;    btst    #NRB_WAIT_REPLY,nr_Flags+3(a3)
  1357. ;    beq.s    .D
  1358. ;    lea    NotifyPort(a5),a0
  1359. ;    CALL    WaitPort
  1360. ;    bsr    GetNotify
  1361. .D    rts
  1362.  
  1363. * Handle replies of Notify message
  1364. GetNotify:
  1365. .A    lea    NotifyPort(a5),a0
  1366.     CALL    GetMsg
  1367.     tst.l    d0
  1368.     beq.s    .E
  1369.     move.l    d0,a1
  1370.     DBUG1    txgnoti,a1
  1371.     move.l    nm_NReq(a1),a0
  1372.     subq.l    #1,nr_MsgCount(a0)
  1373.     moveq    #NotifyMessage_SIZEOF,d0
  1374.     bsr    FreeMem
  1375.     bra.s    .A
  1376. .E    rts
  1377.  
  1378. *******************************************************
  1379.  
  1380. *******************************************************
  1381.  
  1382. * ENTRY: a2=name, a3=parent dir, d2=data size
  1383. * EXIT:  d1=offset of data, d0=new file, Z-flag
  1384. CreateNewObject:
  1385.     move.w    #ERROR_DISK_FULL,dp_Res2+2(a4)
  1386. CreateNewObj:
  1387.     movem.l    d3/a2-a3,-(sp)
  1388.     move.l    a2,a0
  1389.     moveq    #myf_Name,d3
  1390. .D    addq.l    #1,d3
  1391.     tst.b    (a0)+
  1392.     bne.s    .D
  1393.     addq.l    #1,d3
  1394.     bclr    #0,d3
  1395.     move.l    d3,d0
  1396.     add.l    d2,d0
  1397.     bsr    AllocMem
  1398.     beq.s    .fail
  1399.     move.l    d0,a1
  1400.     lea    myf_First(a3),a0
  1401. .C    move.l    (a0),d0
  1402.     beq.s    .A
  1403.     move.l    d0,a0
  1404.     bra.s    .C
  1405. .A    move.l    a1,(a0)
  1406.     clr.l    myf_Link(a1)
  1407.     move.l    a3,myf_Parent(a1)
  1408.     move.l    d2,myf_Size(a1)
  1409.     add.l    d2,FileSize(a5)
  1410.     move.b    #$80,myf_Type(a1)
  1411.     move.b    d3,myf_DataOffs(a1)
  1412.     clr.b    myf_Locks(a1)
  1413.     lea    myf_Name(a1),a0
  1414. .E    move.b    (a2)+,(a0)+
  1415.     bne.s    .E
  1416.     move.l    d3,d1
  1417.     move.l    a1,d0
  1418. .fail    IFD    DEBUG
  1419.     move.l    d0,-(sp)
  1420.     lea    myf_Name(a1),a2
  1421.     move.l    myf_Size(a1),d0
  1422.     DBUG3    txcreat,a2,a1,d0
  1423.     move.l    (sp)+,d0
  1424.     ENDC
  1425.     movem.l    (sp)+,d3/a2-a3
  1426.     rts
  1427.  
  1428. * Delete file in a1
  1429. * ENTRY: a1=file
  1430. * EXIT:  d0=success, Z-flag
  1431. DeleteObj:
  1432.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1433.     move.l    myf_Parent(a1),a0
  1434.     move.l    myf_First(a0),d0
  1435.     sub.l    a0,a0
  1436. .C    move.l    a0,d1
  1437.     move.l    d0,a0
  1438.     tst.l    d0
  1439.     beq    DelErr
  1440.     move.l    myf_Link(a0),d0
  1441.     cmp.l    a1,a0
  1442.     bne.s    .C
  1443. * ENTRY: a1=file d1=pred.
  1444. DeleteObject:
  1445.     move.l    d2,-(sp)
  1446.     moveq    #0,d0
  1447.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1448.     tst.b    myf_Locks(a1)
  1449.     bne.s    .fail
  1450.     tst.b    myf_Type(a1)
  1451.     bmi.s    .C
  1452.     move.w    #ERROR_DIRECTORY_NOT_EMPTY,dp_Res2+2(a4)
  1453.     tst.l    myf_First(a1)    check if dir is empty
  1454.     bne.s    .fail
  1455. .C    move.l    myf_Link(a1),d2    rearrange links
  1456.     move.l    d1,a0
  1457.     tst.l    d1
  1458.     bne.s    .A
  1459.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1460.     move.l    myf_Parent(a1),d1
  1461.     beq.s    .fail        do not delete root
  1462.     move.l    d1,a0
  1463.     lea    myf_First-myf_Link(a0),a0
  1464. .A    move.l    d2,myf_Link(a0)
  1465.     DBUG1    txdel,a1
  1466.     lea    NotifyList(a5),a0
  1467.     bra.s    .D
  1468. .E    move.l    d0,a0
  1469.     cmp.l    myn_Key(a0),a1
  1470.     bne.s    .D
  1471.     clr.l    myn_Key(a0)    check notifications
  1472. .D    move.l    (a0),d0
  1473.     bne.s    .E
  1474.     moveq    #0,d0        free memory
  1475.     move.b    myf_DataOffs(a1),d0
  1476.     move.l    myf_Size(a1),d1
  1477.     add.l    d1,d0
  1478.     sub.l    d1,FileSize(a5)
  1479.     bsr    FreeMem
  1480.     moveq    #1,d0
  1481. .fail    move.l    (sp)+,d2
  1482. DelErr    tst.l    d0
  1483.     rts
  1484.  
  1485. * ENTRY: d0=BPTR parent lock, a0=name (BSTR), d2=access mode
  1486. * EXIT:  d0=APTR lock, Z-flag
  1487. * Must preserve a3
  1488. LocateObject:
  1489.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1490.     move.l    d0,d3
  1491.     bsr    SearchObject
  1492.     bne.s    .A
  1493.     moveq    #ACCESS_READ,d0
  1494.     cmp.l    d0,d2
  1495.     bne.s    .C
  1496.     move.l    d3,d0
  1497.     bsr    CalcFullName
  1498.     bne.s    .A
  1499. .C    moveq    #0,d0
  1500.     bra    LOfail2
  1501. .A    move.l    d0,a2
  1502.     btst    #6,myf_Type(a2)    hidden ?
  1503.     bne.s    .C
  1504.  
  1505. * Create lock on file/dir
  1506. * ENTRY: a2=file, d2=access mode
  1507. * EXIT:  d0=success, Z-flag
  1508. CreateLock:
  1509.     moveq    #0,d0
  1510.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1511.     lea    myf_Locks(a2),a0
  1512.     moveq    #ACCESS_WRITE,d1
  1513.     cmp.l    d1,d2
  1514.     bne.s    .A
  1515.     tst.b    (a0)
  1516.     bne.s    LOfail
  1517.     move.b    d1,(a0)
  1518.     bra.s    .C
  1519. .A    tst.b    (a0)
  1520.     bmi.s    LOfail
  1521.     addq.b    #1,(a0)
  1522. .C    move.w    #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
  1523.     move.l    #myl_SIZEOF,d0
  1524.     bsr    AllocMem
  1525.     beq.s    LOfail
  1526.     move.l    d0,a0
  1527.     clr.l    myl_Link(a0)
  1528.     move.l    a2,myl_Key(a0)
  1529.     move.l    d2,myl_Access(a0)
  1530.     move.l    MyMsgPort(a5),myl_Task(a0)
  1531.     move.l    MyVolumeBPTR(a5),myl_Volume(a0)
  1532.     clr.b    myl_Mode(a0)
  1533.     addq.l    #1,NumLocks(a5)
  1534. LOfail    IFD    DEBUG
  1535.     move.l    d0,d1
  1536.     lsr.l    #2,d1
  1537.     lea    myf_Name(a2),a0
  1538.     DBUG3    txlock,a0,d1,d2
  1539.     ENDC
  1540. LOfail2    tst.l    d0
  1541.     rts
  1542.  
  1543. * Free lock in a1 (APTR)
  1544. FreeLock:
  1545. ;    move.w    #ERROR_UNLOCK_ERROR,dp_Res2+2(a4)
  1546.     IFD    DEBUG
  1547.     move.l    a1,d0
  1548.     lsr.l    #2,d0
  1549.     DBUG1    txulock,d0
  1550.     ENDC
  1551.     move.l    myl_Key(a1),a0
  1552.     tst.b    myf_Locks(a0)
  1553.     beq.s    .A
  1554.     bmi.s    .D
  1555.     subq.b    #1,myf_Locks(a0)
  1556.     bra.s    .A
  1557. .D    clr.b    myf_Locks(a0)
  1558. .A    move.l    #myl_SIZEOF,d0
  1559.     bsr    FreeMem
  1560.     subq.l    #1,NumLocks(a5)
  1561.     rts
  1562.  
  1563. *******************************************************
  1564.  
  1565. * ENTRY: d0=size
  1566. * EXIT:  d0=memory
  1567. AllocMem:
  1568.     add.l    d0,TotalSize(a5)
  1569.     move.l    MyMemPool(a5),d1
  1570.     beq.s    .A
  1571.     move.l    d1,a0
  1572.     CALL    AllocPooled
  1573.     bra.s    .C
  1574. .A    moveq    #1,d1
  1575.     CALL    AllocMem
  1576. .C    tst.l    d0
  1577.     rts
  1578.  
  1579. * ENTRY: d0=size, a1=address
  1580. FreeMem:
  1581.     sub.l    d0,TotalSize(a5)
  1582.     move.l    MyMemPool(a5),d1
  1583.     beq.s    .A
  1584.     move.l    d1,a0
  1585.     CALL    FreePooled
  1586.     rts
  1587. .A    CALL    FreeMem
  1588.     rts
  1589.  
  1590. * Copy BSTR in a0 to string in a1, d0=maxlength without 0
  1591. CopyBSTR2Char:
  1592.     add.l    a0,a0
  1593.     add.l    a0,a0
  1594.     moveq    #0,d1
  1595.     move.b    (a0)+,d1
  1596.     cmp.l    d0,d1
  1597.     bls.s    .C
  1598.     exg.l    d0,d1
  1599.     bra.s    .C
  1600. .A    move.b    (a0)+,(a1)+
  1601. .C    dbra    d1,.A
  1602.     clr.b    (a1)
  1603.     rts
  1604.  
  1605. * Copy string in a0 to BSTR in a1, d0=maxlength without 0
  1606. * EXIT:  d0=BPTR
  1607. CopyChar2BSTR:
  1608.     moveq    #-1,d1
  1609.     addq.l    #1,a1
  1610. .A    addq.l    #1,d1
  1611.     cmp.l    d0,d1
  1612.     bhs.s    .C
  1613.     move.b    (a0)+,(a1)+
  1614.     bne.s    .A
  1615.     subq.l    #1,a1
  1616. .C    clr.b    (a1)
  1617.     sub.l    d1,a1
  1618.     subq.l    #1,a1
  1619.     move.b    d1,(a1)
  1620.     move.l    a1,d0
  1621.     lsr.l    #2,d0
  1622.     rts
  1623.  
  1624. CopyChar2Char:
  1625. * Copy string in a0 to string in a1, d0=maxlength without 0
  1626. .C    move.b    (a0)+,(a1)+
  1627.     beq.s    .A
  1628.     subq.l    #1,d0
  1629.     bne.s    .C
  1630. .A    rts
  1631.  
  1632.  
  1633. * Same as SearchPath, but creates it if not existent
  1634. * ENTRY: TempPath=dirname, d0=lock on dir
  1635. * EXIT:  d0=ptr to file, Z-flag, d1=previous file
  1636. CreatePath:
  1637.     moveq    #1,d1
  1638.     bra.s    SearchP
  1639.  
  1640. * Same as SearchObject, but deletes hidden files
  1641. DelSearchObject
  1642.     bsr    SearchObject
  1643.     beq.s    .A
  1644.     move.l    d0,a1
  1645.     btst    #6,myf_Type(a1)
  1646.     beq.s    .A
  1647.     bsr    DeleteObject    delete hidden file
  1648.     moveq    #0,d0
  1649. .A    tst.l    d0
  1650.     rts
  1651.  
  1652. * Look for object with path
  1653. * ENTRY: a0=filename (BSTR), d0=lock on dir
  1654. * EXIT:  d0=ptr to file, Z-flag, d1=previous file, TempPath=name
  1655. SearchObject:
  1656.     move.l    d0,-(sp)
  1657.     lea    TempPath(a5),a1
  1658.     moveq    #MAXPATH-1,d0
  1659.     bsr    CopyBSTR2Char
  1660.     move.l    (sp)+,d0
  1661. * Same as SearchObject, but name already copied to TempPath
  1662. SearchPath:    ;TempPath=dirname, d0=lock on dir
  1663.     moveq    #0,d1
  1664. SearchP    movem.l    d2-d7/a2-a4,-(sp)
  1665.     move.l    d1,d7
  1666.     lea    RootDir(a5),a1
  1667.     lea    TempPath(a5),a0
  1668. .A    cmp.b    #":",(a0)+    skip volume name
  1669.     beq.s    .E
  1670.     tst.b    -1(a0)
  1671.     bne.s    .A
  1672.     lea    TempPath(a5),a0
  1673. .D    lsl.l    #2,d0        use root or locked dir
  1674.     beq.s    .E
  1675.     move.l    d0,a2
  1676.     move.l    myl_Key(a2),a1    dir represented by lock
  1677. .E
  1678. expand    IFD    EXPAND        expand env:appname.prefs to
  1679.     tst.l    myf_Parent(a1)    env:appname/appname.prefs
  1680.     bne    .A        not in rootdir ?
  1681.     move.l    a0,a4
  1682.     sub.l    a2,a2
  1683. .C    move.b    (a4)+,d0
  1684.     beq.s    .D
  1685.     cmp.b    #"/",d0        check for "/"
  1686.     beq    .A
  1687.     cmp.b    #".",d0
  1688.     bne.s    .C
  1689.     move.l    a4,a2        remember "."
  1690.     bra.s    .C
  1691. .D    move.l    a2,d0
  1692.     beq.s    .A
  1693.     sub.l    a0,d0
  1694.     lea    TempPath(a5),a3
  1695.     sub.l    a3,a4
  1696.     add.l    a4,d0
  1697.     cmp.l    #MAXPATH-1,d0
  1698.     bhs.s    .A
  1699.     move.l    a2,a4
  1700.     lea    prefstx(pc),a3    ends in ".prefs" ?
  1701. .cmp1    move.b    (a4)+,d0
  1702.     cmp.b    (a3)+,d0
  1703.     bne.s    .F
  1704.     tst.b    d0
  1705.     bne.s    .cmp1
  1706.     bra.s    .G
  1707. .F    move.l    a2,a4
  1708.     lea    configtx(pc),a3    ends in ".config" ?
  1709. .cmp2    move.b    (a4)+,d0
  1710.     cmp.b    (a3)+,d0
  1711.     bne.s    .A
  1712.     tst.b    d0
  1713.     bne.s    .cmp2
  1714. .G    move.b    #"/",-1(a2)    insert "/" instead of "."
  1715.     move.l    a0,a3
  1716. .H    move.b    (a3)+,d0    copy first part of filename
  1717.     move.b    d0,(a2)+
  1718.     cmp.b    #"/",d0
  1719.     bne.s    .H
  1720.     move.b    #".",-1(a2)    append ".prefs"
  1721.     lea    prefstx(pc),a3
  1722. .I    move.b    (a3)+,(a2)+
  1723.     bne.s    .I
  1724.     DBUG1    txexp,a0
  1725. .A    ENDC
  1726.  
  1727. * ENTRY: a0=Name, a1=parent dir; mind SP !
  1728. SearchName:
  1729. .A    moveq    #0,d0
  1730. .D    cmp.b    #"/",(a0)    parent dir when starting with /
  1731.     bne.s    .H
  1732.     move.l    myf_Parent(a1),d2
  1733.     beq.s    .fail
  1734.     move.l    d2,a1
  1735.     addq.l    #1,a0
  1736.     bra.s    .D
  1737. .H    tst.b    (a0)        check for empty string
  1738.     beq.s    .G
  1739.     move.l    a0,a4
  1740.     moveq    #0,d3
  1741. .C    addq.l    #1,d3        look for / or end
  1742.     tst.b    (a4)
  1743.     beq.s    .E
  1744.     cmp.b    #":",(a4)
  1745.     beq.s    .fail
  1746.     cmp.b    #"/",(a4)+
  1747.     bne.s    .C
  1748. .E    move.b    myf_Type(a1),d2
  1749.     bmi.s    .fail
  1750.     btst    #6,d2
  1751.     beq.s    .J
  1752.     tst.l    d7        check for CreatePath
  1753.     beq.s    .fail
  1754.     clr.b    myf_Type(a1)    convert hidden to dir
  1755. .J    move.l    a1,d2
  1756.     bsr    SearchEntry    search in dir
  1757.     bne.s    .F
  1758.     tst.l    d7        check for CreatePath
  1759.     beq.s    .G
  1760.     movem.l    d1-d3/a0/a2-a4,-(sp)
  1761.     move.l    d2,a3
  1762.     move.l    a0,a2
  1763.     move.l    a0,a4
  1764.     subq.l    #1,d3
  1765.     add.l    d3,a4
  1766.     move.b    (a4),d3
  1767.     clr.b    (a4)
  1768.     moveq    #0,d2
  1769.     bsr    CreateNewObj    create new dir
  1770.     move.b    d3,(a4)
  1771.     move.l    d0,a1
  1772.     movem.l    (sp)+,d1-d3/a0/a2-a4
  1773.     tst.l    d0
  1774.     beq.s    .G
  1775.     clr.b    myf_Type(a1)
  1776. .F    move.l    a4,a0
  1777.     bra.s    .A        continue looking for / or end
  1778. .G    move.l    a1,d0
  1779. .fail    IFD    DEBUG
  1780.     lea    TempPath(a5),a0
  1781.     moveq    #0,d2
  1782.     tst.l    d0
  1783.     beq.s    .I
  1784.     move.b    myf_Type(a1),d2
  1785. .I    DBUG3    txfnd,a0,d0,d2
  1786.     ENDC
  1787.     movem.l    (sp)+,d2-d7/a2-a4
  1788.     tst.l    d0
  1789.     rts
  1790.  
  1791. * ENTRY: a2=name, a3=parent dir, d2=data size
  1792. * EXIT:  d1=offset of data, d0=new file, Z-flag
  1793.  
  1794.  
  1795. * Look for object in dir
  1796. * ENTRY: a0=file/dir name, a1=ptr to dir, d3=length of name
  1797. * EXIT:  a1=ptr to file or 0, Z-flag
  1798. SearchEntry:
  1799.     moveq    #0,d5
  1800.     moveq    #0,d6
  1801.     move.l    myf_First(a1),d0
  1802.     sub.l    a1,a1
  1803. .C    move.l    a1,d1
  1804.     move.l    d0,a1
  1805.     tst.l    d0
  1806.     beq.s    .fail
  1807.     move.l    myf_Link(a1),d0
  1808.     lea    myf_Name(a1),a2
  1809.     move.l    a0,a3
  1810.     move.l    d3,d4
  1811.     bra.s    .E
  1812. .A    move.b    (a2)+,d5
  1813.     move.b    CharTable(a5,d5.l),d5
  1814.     move.b    (a3)+,d6
  1815.     move.b    CharTable(a5,d6.l),d6
  1816.     cmp.b    d5,d6
  1817.     bne.s    .C
  1818. .E    subq.l    #1,d4
  1819.     bne.s    .A
  1820.     tst.b    (a2)
  1821.     bne.s    .C
  1822.     IFD    DEBUG
  1823.     lea    myf_Name(a1),a3
  1824.     DBUG1    txentry,a3
  1825.     ENDC
  1826. .fail    move.l    a1,d0
  1827.     rts
  1828.  
  1829. *Splits path with file into path=TempPath and file=TempName
  1830. SplitPath
  1831.     move.l    a2,-(sp)
  1832.     lea    TempPath(a5),a0
  1833.     move.l    a0,a1
  1834. .A    tst.b    (a0)+
  1835.     bne.s    .A
  1836. .D    cmp.b    #"/",-(a0)
  1837.     beq.s    .C
  1838.     cmp.b    #":",(a0)
  1839.     beq.s    .C
  1840.     cmp.l    a0,a1
  1841.     bne.s    .D
  1842.     move.l    a0,a1
  1843.     bra.s    .G
  1844. .C    move.l    a0,a1
  1845.     addq.l    #1,a1
  1846. .G    lea    TempName(a5),a2
  1847. .E    move.b    (a1)+,(a2)+
  1848.     bne.s    .E
  1849.     cmp.b    #":",(a0)
  1850.     bne.s    .F
  1851.     addq.l    #1,a0
  1852. .F    clr.b    (a0)
  1853.     move.l    (sp)+,a2
  1854.     IFD    DEBUG
  1855.     lea    TempPath(a5),a0
  1856.     lea    TempName(a5),a1
  1857.     DBUG2    txsplit,a0,a1
  1858.     ENDC
  1859.     rts
  1860.  
  1861. * ENTRY: a1=object
  1862. * EXIT:  a0=full name (root name not included) in TempPath
  1863. * Only used by CalcFullName
  1864. GetFullName:
  1865.     move.l    d2,-(sp)
  1866.     lea    TempPath+MAXPATH+MAXNAME-1(a5),a0
  1867.     clr.b    (a0)
  1868.     move.w    #MAXPATH+MAXNAME-1,d2
  1869. .A    move.l    myf_Parent(a1),d0
  1870.     beq.s    .ok
  1871.     lea    myf_Name(a1),a1
  1872.     moveq    #-1,d1
  1873. .C    addq.l    #1,d1
  1874.     tst.b    (a1)+
  1875.     bne.s    .C
  1876.     subq.l    #1,a1
  1877.     sub.w    d1,d2
  1878.     bmi.s    .ok
  1879.     tst.b    (a0)
  1880.     beq.s    .D
  1881.     move.b    #"/",-(a0)
  1882.     subq.w    #1,d2
  1883.     bra.s    .D
  1884. .E    move.b    -(a1),-(a0)
  1885. .D    dbra    d1,.E
  1886.     move.l    d0,a1
  1887.     bra.s    .A
  1888. .ok    move.l    (sp)+,d2
  1889.     rts
  1890.  
  1891. * ENTRY: TempPath=name, d0=BPTR parent lock
  1892. * EXIT: d0=new file
  1893. * Only used by LocateObject and UpNoti
  1894. CalcFullName:
  1895.     movem.l    d2-d6/a2-a4,-(sp)
  1896.     moveq    #0,d4            d4=return code
  1897.     tst.b    WriteProtected(a5)
  1898.     bne    .fail
  1899.     tst.l    Copyfrom(a5)
  1900.     beq    .fail
  1901.     bsr    CreatePath
  1902.     beq    .fail
  1903.     move.l    d0,a1
  1904.     move.l    d0,a2
  1905.     move.b    #$40,myf_Type(a1)    a2=new hidden file
  1906.     bsr    GetFullName
  1907.     DBUG1    txfull,a0
  1908.     lea    TempPath(a5),a1
  1909.     moveq    #MAXPATH-2,d0
  1910.     bsr    CopyChar2BSTR
  1911.     move.l    d0,d5            d5=BSTR full name
  1912.  
  1913.     move.l    #fib_SIZEOF+fh_SIZEOF,d0
  1914.     bsr    AllocMem
  1915.     beq    .fail
  1916.     move.l    d0,a3            a3=File info block
  1917.     lea    fib_SIZEOF(a3),a4    a4=file handle
  1918.  
  1919.     move.l    Copyfrom(a5),a0
  1920.     move.l    dol_Lock(a0),d1
  1921.     move.l    dol_List(a0),d6    
  1922.     bra.s    .D
  1923. .C    tst.l    d6
  1924.     beq    .fail2
  1925.     move.l    d6,a0
  1926.     move.l    (a0),d6        al_Next
  1927.     move.l    4(a0),d1    al_Lock
  1928. .D    move.l    d1,CopyfromLock(a5)
  1929.     move.l    d1,a0
  1930.     add.l    a0,a0
  1931.     add.l    a0,a0
  1932.     move.l    fl_Task(a0),CopyfromPort(a5)
  1933.     move.l    d5,d2
  1934.     moveq    #ACCESS_READ,d3
  1935.     moveq    #ACTION_LOCATE_OBJECT,d0
  1936.     bsr    DoPacket
  1937.     beq    .C
  1938.  
  1939.     move.l    d0,d3            d3=lock on file
  1940.     move.l    d3,d1
  1941.     move.l    a3,d2
  1942.     lsr.l    #2,d2
  1943.     moveq    #ACTION_EXAMINE_OBJECT,d0
  1944.     bsr    DoPacket
  1945.     move.l    d0,-(sp)
  1946.     move.l    d3,d1
  1947.     moveq    #ACTION_FREE_LOCK,d0
  1948.     bsr    DoPacket
  1949.     move.l    (sp)+,d0
  1950.     beq.s    .fail2
  1951.     tst.l    fib_DirEntryType(a3)
  1952.     bmi.s    .A
  1953.     clr.b    myf_Type(a2)        turn hidden into dir
  1954.     move.l    a2,d4
  1955.     bra.s    .fail2
  1956.  
  1957. .A    move.l    a4,d1
  1958.     lsr.l    #2,d1
  1959.     move.l    CopyfromLock(a5),d2
  1960.     move.l    d5,d3
  1961.     move.l    #ACTION_FINDINPUT,d0
  1962.     bsr    DoPacket
  1963.     beq.s    .fail2
  1964.     movem.l    a2/a3,-(sp)
  1965.     move.l    fib_Size(a3),d2
  1966.     move.l    myf_Parent(a2),a3
  1967.     lea    myf_Name(a2),a2
  1968.     bsr    CreateNewObject
  1969.     movem.l    (sp)+,a2/a3
  1970.     beq.s    .fail3
  1971.     move.l    d0,d2
  1972.     add.l    d1,d2
  1973.     move.l    a2,a1
  1974.     move.l    d0,a2
  1975.     move.b    #$a0,myf_Type(a2)
  1976.     bsr    DeleteObj
  1977.     beq.s    .fail3
  1978.     move.l    fh_Arg1(a4),a4
  1979.     move.l    a4,d1
  1980.     move.l    fib_Size(a3),d3
  1981.     moveq    #ACTION_READ,d0
  1982.     bsr    DoPacket
  1983.     bsr    UpdateNotify
  1984. .fail3    move.l    a4,d1
  1985.     move.l    #ACTION_END,d0
  1986.     bsr    DoPacket
  1987.     move.l    a2,d4
  1988. .fail2    move.l    a3,a1
  1989.     move.l    #fib_SIZEOF+fh_SIZEOF,d0
  1990.     bsr    FreeMem
  1991. .fail    move.l    d4,d0
  1992.     movem.l    (sp)+,d2-d6/a2-a4
  1993.     rts
  1994.  
  1995. *******************************************************
  1996.  
  1997.     IFD    DEBUG
  1998. RawHook    move.l    a6,-(sp)
  1999.     move.l    4.w,a6
  2000.     jsr    _LVORawPutChar(a6)
  2001.     move.l    (sp)+,a6
  2002.     rts
  2003.  
  2004. wait_c:
  2005.     movem.l    d0-d1/a0-a1,-(sp)
  2006.     moveq    #0,d0
  2007.     moveq    #0,d1
  2008.     bset    #12,d1
  2009.     jsr    _LVOSetSignal(a6)
  2010.     moveq    #0,d0
  2011.     bset    #12,d0
  2012.     jsr    _LVOWait(a6)    wait for CTRL-C
  2013.     movem.l    (sp)+,d0-d1/a0-a1
  2014.     rts
  2015.  
  2016.     IFD    VERBOSE
  2017. txstart    dc.b    "Handler started, A5=$%lx.",10,0
  2018. txend    dc.b    "Handler ended, FileSize=%ld, TotalSize=%ld.",10,0
  2019. txcopy    dc.b    "Copyfrom=$%lx.",10,0
  2020. txpack    dc.b    "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
  2021. txres    dc.b    "Result1=$%lx, Result2=%ld.",10,0
  2022. txpkt    dc.b    "  Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
  2023. txerr1    dc.b    "  %ld: Unknown Action.",10,0
  2024.  
  2025. txopeno    dc.b    "  Oldopen lock=$%lx.",10,0
  2026. txopenn    dc.b    "  Newopen lock=$%lx.",10,0
  2027. txcreat    dc.b    "  Created file %s=$%lx size=%ld.",10,0
  2028. txread    dc.b    "  Read %ld of %ld bytes, pos=%ld.",10,0
  2029. txwrite    dc.b    "  Wrote %ld bytes, pos=%ld, size=%ld.",10,0
  2030. txwins    dc.b    "  Inserted %ld bytes at %ld.",10,0
  2031. txseek    dc.b    "  Seeked, filepos=%ld.",10,0
  2032. txdel    dc.b    "  Deleted $%lx.",10,0
  2033.  
  2034. txlock    dc.b    "  Locked %s=$%lx mode %ld.",10,0
  2035. txulock    dc.b    "  Unlocked $%lx.",10,0
  2036. txexam    dc.b    "  Examined file=$%lx.",10,0
  2037. txexnx    dc.b    "  Examined next file=$%lx.",10,0
  2038. txfnd    dc.b    "    Found %s=$%lx type=$%lx.",10,0
  2039. txentry    dc.b    "    Found entry %s.",10,0
  2040. txsplit    dc.b    "    Splitted ->%s,%s.",10,0
  2041. txfull    dc.b    "    Full name: %s.",10,0
  2042. txexp    dc.b    "    Expanded path to %s.",10,0
  2043.  
  2044. txanoti    dc.b    "  Added noti $%lx->$%lx on %s key=$%lx.",10,0
  2045. txrnoti    dc.b    "  Removed noti $%lx->$%lx.",10,0
  2046. txcnoti    dc.b    "  Checking noti on %s.",10,0
  2047. txunoti    dc.b    "    Updated noti on %s key=$%lx.",10,0
  2048. txsnoti    dc.b    "    Sent signal to %s for %s.",10,0
  2049. txmnoti    dc.b    "    Sent message $%lx to %s for %s.",10,0
  2050. txgnoti    dc.b    "    Got message $%lx.",10,0
  2051.     ENDC
  2052.  
  2053.     IFND    VERBOSE
  2054. txstart    dc.b    "Handler started, A5=$%lx.",10,0
  2055. txend    dc.b    "Handler ended, FileSize=%ld, TotalSize=%ld.",10,0
  2056. txcopy    dc.b    "Copyfrom=$%lx.",10,0
  2057. txpack    dc.b    "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
  2058. txres    dc.b    "Result1=$%lx, Result2=%ld.",10,0
  2059. txpkt    dc.b    0;"  Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
  2060. txerr1    dc.b    "  %ld: Unknown Action.",10,0
  2061.  
  2062. txopeno    dc.b    0;"  Oldopen lock=$%lx.",10,0
  2063. txopenn    dc.b    0;"  Newopen lock=$%lx.",10,0
  2064. txcreat    dc.b    "  Created file %s=$%lx size=%ld.",10,0
  2065. txread    dc.b    0;"  Read %ld of %ld bytes, pos=%ld.",10,0
  2066. txwrite    dc.b    0;"  Wrote %ld bytes, pos=%ld, size=%ld.",10,0
  2067. txwins    dc.b    0;"  Inserted %ld bytes at %ld.",10,0
  2068. txseek    dc.b    0;"  Seeked, filepos=%ld.",10,0
  2069. txdel    dc.b    "  Deleted $%lx.",10,0
  2070.  
  2071. txlock    dc.b    "  Locked %s=$%lx mode %ld.",10,0
  2072. txulock    dc.b    0;"  Unlocked $%lx.",10,0
  2073. txexam    dc.b    0;"  Examined file=$%lx.",10,0
  2074. txexnx    dc.b    0;"  Examined next file=$%lx.",10,0
  2075. txfnd    dc.b    0;"    Found %s=$%lx type=$%lx.",10,0
  2076. txentry    dc.b    0;"    Found entry %s.",10,0
  2077. txsplit    dc.b    0;"    Splitted ->%s,%s.",10,0
  2078. txfull    dc.b    0;"    Full name: %s.",10,0
  2079. txexp    dc.b    "    Expanded path to %s.",10,0
  2080.  
  2081. txanoti    dc.b    "  Added noti $%lx->$%lx on %s key=$%lx.",10,0
  2082. txrnoti    dc.b    "  Removed noti $%lx->$%lx.",10,0
  2083. txcnoti    dc.b    0;"  Checking noti on %s.",10,0
  2084. txunoti    dc.b    0;"    Updated noti on %s key=$%lx.",10,0
  2085. txsnoti    dc.b    0;"    Sent signal to %s for %s.",10,0
  2086. txmnoti    dc.b    0;"    Sent message $%lx to %s for %s.",10,0
  2087. txgnoti    dc.b    0;"    Got message $%lx.",10,0
  2088.     ENDC
  2089.  
  2090.     ENDC
  2091.  
  2092.