include dos/dosasl.i ; PatchList.s ; This program will print on the standard output stream a list of all ; active patches made to the system since SafeFunction was launched. ; If it can, it will use the Function Descriptors (FD files) to tell ; the name of a patched function in a library. ; Usage: PatchList [NOFD] [FDDIR ; The default fd directory is "FD:". ; This program and the source are public domain. Author: ; Frédéric Delacroix ; 5 rue d'Artres ; 59269 Quérénaing ; FRANCE ; *************** declarations from SafeFunction.s ******************** rsreset ; these variables are protected by the semaphore var_HeadPtr rs.l 1 var_HeadPtr1 rs.l 1 var_Patch rs.l 1 var_Patch1 rs.l 1 var_Patch2 rs.l 1 var_MainHeader rs.l 1 ; first LibHeader var_OldSetFunc rs.l 1 ; points to real SetFunction() var_SetFuncSemaphore rs.b SS_SIZE var_SIZEOF rs.w 0 STRUCTURE LibHeader,0 APTR libh_LibBase ; points to patched library APTR libh_Patches ; points to list of patches APTR libh_NextLib ; points to next library header LABEL libh_SIZEOF STRUCTURE LibPatch,0 USHORT libp_JMP ; JMP instruction APTR libp_OldFunc ; old (before patch) function APTR libp_NewFunc ; new (after patch) function SHORT libp_Offset ; offset in jump table APTR libp_NextPatch ; points to next patch in library LABEL libp_SIZEOF MAGIC_OFFSET EQU $2357 ; prime numbers :-| ; ********************************************************************* VERSION MACRO dc.b '1.0' ENDM move.l 4.w,a6 moveq #100,d7 move.l a6,Exec.Base lea DOS.Name(pc),a1 moveq #39,d0 ; kickstart 3.0 required (by SafeFunction) jsr _LVOOpenLibrary(a6) move.l d0,DOS.Base beq NoDOS moveq #20,d7 move.l d0,a6 move.l #Bienvenue.MSG,d1 jsr _LVOPutStr(a6) move.l #Args.Template,d1 move.l #Args.Array,d2 moveq #0,d3 jsr _LVOReadArgs(a6) move.l d0,Args.RDArgs beq CloseDOS tst.l Args.Array bne.s NoFD move.l Args.Array+4(pc),d1 move.l #ACCESS_READ,d2 jsr _LVOLock(a6) move.l d0,d1 bne.s FDDirOK move.l #NoFDDir.MSG,d1 jsr _LVOPutStr(a6) st Args.Array bra.s NoFD FDDirOK jsr _LVOCurrentDir(a6) move.l d0,OldDir.Lock NoFD moveq #10,d7 move.l Exec.Base(pc),a6 jsr _LVOForbid(a6) lea Semaphore.Name(pc),a1 jsr _LVOFindSemaphore(a6) move.l d0,SafeFunction.Semaphore beq NoSafeFunction move.l d0,a0 jsr _LVOObtainSemaphoreShared(a6) jsr _LVOPermit(a6) move.l SafeFunction.Semaphore(pc),a5 move.l var_MainHeader-var_SetFuncSemaphore(a5),a5 move.l DOS.Base(pc),a6 moveq #0,d7 NextLibrary move.l #SIGBREAKF_CTRL_C,d1 jsr _LVOCheckSignal(a6) tst.l d0 beq.s .NoBreak move.l #ERROR_BREAK,d1 moveq #0,d2 jsr _LVOPrintFault(a6) moveq #5,d7 bra EndOfList .NoBreak move.l libh_NextLib(a5),d0 beq EndOfList move.l d0,a5 tst.l Args.Array bne.s .NoFDFile move.l libh_LibBase(a5),a1 move.l LN_NAME(a1),a0 lea LibName.Buffer,a1 move.l #100,d0 .CopyName.Loop move.b (a0)+,(a1)+ cmp.b #'.',-1(a1) beq.s .NameCopied tst.b -1(a1) dbeq d0,.CopyName.Loop .NameCopied move.b #'_',-1(a1) move.b #'l',(a1)+ move.b #'i',(a1)+ move.b #'b',(a1)+ move.b #'.',(a1)+ move.b #'f',(a1)+ move.b #'d',(a1)+ clr.b (a1) move.l #LibName.Buffer,d1 move.l #MODE_OLDFILE,d2 jsr _LVOOpen(a6) move.l d0,FDFile.Handle .NoFDFile move.l #PatchedLib.Fmt,d1 move.l libh_LibBase(a5),a0 move.l a0,-(sp) move.l LN_NAME(a0),-(sp) move.l sp,d2 jsr _LVOVPrintf(a6) addq.l #8,sp move.l libh_Patches(a5),a4 NextPatch cmp.w #MAGIC_OFFSET,libp_Offset(a4) beq.s .SkipPatch move.l libp_OldFunc(a4),PrintArg.Old move.l libp_NewFunc(a4),PrintArg.New move.w libp_Offset(a4),d0 move.w d0,PrintArg.Offset bsr ReadFuncName move.l d0,PrintArg.Name move.l #PatchedFunc.Fmt,d1 move.l #PrintArgs,d2 jsr _LVOVPrintf(a6) .SkipPatch move.l libp_NextPatch(a4),d0 beq.s .CloseFD move.l d0,a4 bra.s NextPatch .CloseFD move.l FDFile.Handle(pc),d1 beq NextLibrary jsr _LVOClose(a6) clr.l FDFile.Handle move.w #-24,FDFile.CurrentOffset bra NextLibrary EndOfList move.l SafeFunction.Semaphore(pc),a0 move.l Exec.Base(pc),a6 jsr _LVOReleaseSemaphore(a6) FreeFDDir move.l OldDir.Lock(pc),d1 beq.s FreeArgs move.l DOS.Base(pc),a6 jsr _LVOCurrentDir(a6) move.l d0,d1 jsr _LVOUnLock(a6) FreeArgs move.l DOS.Base(pc),a6 move.l Args.RDArgs(pc),d1 jsr _LVOFreeArgs(a6) CloseDOS move.l DOS.Base(pc),a1 move.l Exec.Base(pc),a6 jsr _LVOCloseLibrary(a6) NoDOS move.l d7,d0 rts NoSafeFunction jsr _LVOPermit(a6) move.l #NoSafeFunction.MSG,d1 move.l DOS.Base(pc),a6 jsr _LVOPutStr(a6) bra.s FreeArgs ReadFDLine ; (D0)EndFlag=ReadFDLine(DOSBase)(a6) movem.l d1-d2/a0-a2,-(sp) lea FDLine.Buffer,a2 move.l #254,d2 tst.l FDFile.Handle beq.s .EOF .Loop move.l FDFile.Handle(pc),d1 jsr _LVOFGetC(a6) cmp.l #-1,d0 beq.s .EOF cmp.b #10,d0 beq.s .EOL tst.w d2 ble.s .Loop ; skip extraneous characters until EOL or EOF move.b d0,(a2)+ dbra d2,.Loop .EOL moveq #0,d0 .Return clr.b (a2) movem.l (sp)+,d1-d2/a0-a2 rts .EOF moveq #-1,d0 bra.s .Return ReadFuncName ; (D0)Name=ReadFuncName(Offset)(D0) cmp.w #-6,d0 bne.s .NotLIBOPEN move.l #LIBOPEN.Name,d0 bra .Return .NotLIBOPEN cmp.w #-12,d0 bne.s .NotLIBCLOSE move.l #LIBCLOSE.Name,d0 bra .Return .NotLIBCLOSE cmp.w #-18,d0 bne.s .NotLIBEXPUNGE move.l #LIBEXPUNGE.Name,d0 bra .Return .NotLIBEXPUNGE cmp.w #-24,d0 bne.s .NotLIBRESERVED move.l #LIBRESERVED.Name,d0 bra .Return .NotLIBRESERVED movem.l d1/d3/a2-a3,-(sp) move.l d0,d3 bra.s .BeginLoop .ReadIt bsr ReadFDLine tst.l d0 beq.s .LineRead .NotAvailable move.l #NotAvailable.MSG,d0 bra.s .ReturnIt .LineRead lea FDLine.Buffer,a2 cmp.b #'*',(a2) ; comment beq.s .ReadIt cmp.w #'##',(a2) beq.s .SpecialCommand sub.w #6,FDFile.CurrentOffset .BeginLoop cmp.w FDFile.CurrentOffset,d3 blt.s .ReadIt bne.s .NotAvailable lea FDLine.Buffer,a2 lea FuncName.Buffer,a3 .NameLoop move.b (a2)+,d0 beq.s .ReturnBuf cmp.b #'(',d0 ; do not copy arguments for function beq.s .ReturnBuf move.b d0,(a3)+ clr.b (a3) bra.s .NameLoop .SpecialCommand cmp.l #'bias',2(a2) ; ignore other commands bne.s .ReadIt move.l a2,d1 addq.l #6,d1 move.l #Long.Buffer,d2 jsr _LVOStrToLong(a6) cmp.l #-1,d0 beq.s .ReadIt move.w Long.Buffer+2(pc),d0 neg.w d0 move.w d0,FDFile.CurrentOffset add.w #6,FDFile.CurrentOffset ; so that the next func has the right offset bra .ReadIt .ReturnBuf move.l #FuncName.Buffer,d0 .ReturnIt movem.l (sp)+,d1/d3/a2-a3 .Return rts Exec.Base dc.l 0 DOS.Base dc.l 0 Args.Array dc.l 0,FD.Name Args.RDArgs dc.l 0 OldDir.Lock dc.l 0 SafeFunction.Semaphore dc.l 0 FDFile.Handle dc.l 0 Long.Buffer dc.l 0 PrintArgs ; arguments for VPrintf()ing a patch line PrintArg.Offset dc.w 0 PrintArg.New dc.l 0 PrintArg.Old dc.l 0 PrintArg.Name dc.l 0 FDFile.CurrentOffset dc.w -24 DOS.Name dc.b 'dos.library',0 Bienvenue.MSG dc.b 'PatchList ' VERSION dc.b ' by F.Delacroix, public domain.',10,0 Args.Template dc.b 'NOFD/S,FDDIR/K',0 FD.Name dc.b 'FD:',0 NoFDDir.MSG dc.b ' Cannot lock onto specified FD directory. NOFD assumed.',0 Semaphore.Name dc.b 'SafeFunction.Semaphore',0 NoSafeFunction.MSG dc.b ' SafeFunction is not installed in your system.',10,0 PatchedLib.Fmt dc.b 10,'Library: %s (%lx)',10 dc.b ' Offset New function Old function Name',10,0 PatchedFunc.Fmt dc.b ' %4.d $%lx $%lx %s',10,0 NotAvailable.MSG dc.b 'N/A',0 LIBOPEN.Name dc.b 'LIB_OPEN',0 LIBCLOSE.Name dc.b 'LIB_CLOSE',0 LIBEXPUNGE.Name dc.b 'LIB_EXPUNGE',0 LIBRESERVED.Name dc.b 'LIB_RESERVED',0 section Buffers,BSS LibName.Buffer ds.b 108 FDLine.Buffer ds.b 256 FuncName.Buffer ds.b 256