;TOSAAAABGJFAAAACFHJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPPPPMDPC

;My first patcher (c) Wizard/GPS 27/07/1994

;Converted to Ultimate Patch System format by SAA/Glenz PointS in 1995.

;I decided to patch DOS function DELETE in order to prevent user-non-alowed
;actions. Hehehe... c00l. Every time OS wanna delete something, requester
;pops up and ask for our permission. c00l. :)

;I've just figured out that some memory should be allocated.
;Silly me, no wonder it crashed after some brain transplants in memory. ;)
;I'll fix it as sonn as... hm. Soon enough.

;Date 02/08/1994 Wow! That's something I call Soon. I surprised even myself.
;Well, se far so good. Code is fixed not to crash system...
;I don't expect any fee - just spare my life. ;) [v1.0]

;Date 03/08/1994 Great! I've just got back from, hm... swiming session. ;)
;I should do it more often. As soon as I got back, idea just poped out!
;This proggy had a really nasty bug - it crashed every time when trying
;to deallocate allocated memory. I didn't know where the bug was at the
;time, but few secs ago I realized something very stupid. I passed
;deallocate memory pointer to address of variable instead of passing it
;to value stored in veriable (I mixed this sentence, but instead of
;move X,d0, I did something like move #X,d0. Got it? :->).
;Won't happen again. ;)

;Last decision - when user is trying to get out from the patcher and
;restore old Delete() what then? I decided ti call old Delete() at
;this moment which means that at the time user has selected killing
;patcher, old Delete() function is active and called through my proggy.
;Got it? Exit from patcher = call Delete() for the first time in
;new 'life'. :->

;Date 05/08/1994 New option added. This proggy was unable to show name
;of the file that should be deleted. I fixed it today. [v1.1]

;Date 09/08/1994 I've just added something new, at SAA's request. If you
;have deleted <NAME> file DPatch'll let <NAME.info> deletes automatically.
;This ability includes also <NAME.info...info> files NOT even supported
;by Workbench! :-> Yea, but I thought it would be nice... ;) [v1.2]

;Date 09/08/1994 Fixed incompatibility problems with DOPUS. Read doc
;for more info. There's a kind of bug now - if you choose not to delete
;certain file, you'll be unable to delete it right after this delete
;call. You'll have to delete something else first, just to remove
;old name from buffer. Sorry for this. [v1.2]

;Date 11/08/1994 I've missed something. Oooops. This proggy doesn't
;work with OLD dos.library (ver$ < 39.00). I built in checkpoint for
;this, but it seems I forgot stopping the program. Silly me, again. ;)

	incdir	"include:"
	include	"libs/exec.i"
	include	"libs/dos.i"
	include	"libs/reqtools.i"
	incdir	"ups:"
	include	"ups.i"

	SECTION	aa,code_p

Start	moveq	#0,d0
	rts
.end	blk.b	32-(.end-Start)
	dc.l	pfsControlLong
	dc.l	0			; pointer to next patcher
	dc.l	0			; pointer to prev patcher
	dc.l	UPSMainVersion		; minimum version of UPS to start
	dc.l	UPSMainVersion		; version of UPS which was used
					; while patcher was developed
	dc.l	PatcherName		; pointer to name of patcher
	dc.w	0,0			; version
	dc.l	CoderName		; pointer to name of programmer
	dc.l	VerString		; pointer to $VER: string
	dc.l	PatcherIDString		; listview entry
	dc.l	pfsDisableable		; flags
	dc.l	0			; status of flags
execbase
	dc.l	0			; exec base
intbase	dc.l	0			; intuition base
gadtbase
	dc.l	0			; gadtools base
dosbase	dc.l	0			; dos base
gfxbase	dc.l	0			; graphics base
cxbase	dc.l	0			; commodities base
laybase	dc.l	0			; layers base
upsbase	dc.l	0			; UPS lib base
	dc.l	0			; pointer to init routine
	dc.l	0			; pointer to exit routine
	dc.l	0			; pointer to prefs routine
	dc.l	0			; pointer to cx keys to call prefs rout
	dc.l	Resources		; pointer to structure of requested
    					; opened resources
	dc.l	Patch1			; pointer to structure for patches
	dc.l	pls1			; pointer to pls structure
	dc.l	0			; pointer to main UPS msg port
	dc.l	0			; pointer to rexx port
	dc.l	0			; pointer to pxs structure
	dc.l	0,0,0
	dc.l	pfsControlLong
	dc.l	Start			; pointer to the beginning of struct

PatcherIDString
PatcherName
	dc.b	'DPatch',0
	even
CoderName
	dc.b	'Goran Paulin',0
	even
VerString
	dc.b	'$VER: DPatch V2.0',0
	even

	cnop	0,4

Resources
	dc.l	0			; pointer to next entry
	dc.l	0			; pointer to previous entry
	dc.l	rt_Library		; type of resource
	dc.l	100			; resource id
	dc.l	0			; flags
	dc.l	res1name		; pointer to name of resource
res1base
	dc.l	0			; base of opened resource
	dc.l	0			; version, if needed
	blk.l	8			; ...to put in data regs
	dc.l	0			; user open rout for user type
	dc.l	0			; user close rout for user type
	dc.l	0			; pointer to name for user type
	dc.l	0,0

res1name
	dc.b	'dos.library',0
	cnop	0,4



Patch1
	dc.l	0			; pointer to next patch
	dc.l	0			; pointer to prev patch
	dc.l	100			; priority, less runs first
	dc.l	Start			; pointer to parent Patcher
	dc.l	Patch1ID		; listview entry
	dc.l	Patch1purpose		; pointer to purpose string
	dc.l	100			; id of resource to be patched
	dc.l	mpsDisableable		; flags
	dc.l	0			; status of flags
	dc.l	-72			; offset to change
	dc.l	MyDelete		; pointer to new routine
old	dc.l	0			; pointer to old routine
	dc.l	0			; pointer to pns structure
	dc.l	0			; notified when enabled/disabled
	dc.l	0			; install rout for user type
	dc.l	0			; uninstall rout for user type
	dc.l	0			; pointer to init routine
	dc.l	0			; pointer to exit routine
	dc.l	pls1			; pointer to pls structure
	dc.l	0,0,0,0


Patch1ID
pls1ID
	dc.b	'DeleteFile()',0		; 27
	even
Patch1purpose
	dc.b	'improving',0			; 16
	cnop	0,4



pls1	dc.l	0			; pointer to next link
	dc.l	0			; pointer to prev link
	dc.l	pls1ID			; listview string
	dc.l	0			; pointer to prefs routine
	dc.l	plsDisableable		; flags
	dc.l	0			; status
	dc.l	Patch1
	dc.l	0

	cnop	0,4






MyDelete
	movem.l	d0-d7/a0-a6,-(a7)

; Test if something's trying to delete same file.
; In this case we simply use previous answer stored in Choice.

	move.l	d1,a0			; new file name
	lea	FileName(pc),a1		; old file name
CompareSame
	move.b	(a0)+,d0
	cmpi.b	#'a',d0			; uppercase conversion (!)
	blt.b	LeaveSame1			; why?
	cmpi.b	#'z',d0			; Extras!=EXTRAS >REMEMBER!<
	bgt.b	LeaveSame1
	sub.b	#32,d0			; a -> A, z -> Z
LeaveSame1
	move.b	(a1)+,d2
	cmpi.b	#'a',d2			; uppercase conversion (!)
	blt.b	LeaveSame2			; why?
	cmpi.b	#'z',d2			; Extras!=EXTRAS >REMEMBER!<
	bgt.b	LeaveSame2
	sub.b	#32,d2			; a -> A, z -> Z
LeaveSame2
	cmpi.b	#0,d0			; test new file name end
	beq.s	TestMatchSame
	cmp.b	d0,d2			; COMPARE names
	beq.s	CompareSame		; if ONLY one char is wrong -> skip
	bra.s	NotSameFile		; doesn't match!
TestMatchSame
	cmpi.b	#0,d2			; test old file name end
	bne.s	NotSameFile		; doesn't match!
FileMatch
	bra.w	OldChoice
	
NotSameFile
	lea	PopUp(pc),a0		; default = pop up = 0
	move.b	#1,(a0)

; Check if something's trying to delete appropriate .info file
; Delete it automatically in this case!

AddInfo
	lea	FileName(pc),a0		; form NAME.info,$0
	clr.l	d0			; prepare d0
	move.b	NameLen(pc),d0
	subq.l	#1,d0
	adda.l	d0,a0
	move.b	#'.',(a0)+
	move.l	#'info',(a0)+
	move.b	#0,(a0)			; file name formed

	move.l	d1,a0			; new file name
	lea	FileName(pc),a1		; old file name
Compare
	move.b	(a0)+,d0
	cmpi.b	#'a',d0			; uppercase conversion (!)
	blt.b	Leave1			; why?
	cmpi.b	#'z',d0			; Extras!=EXTRAS >REMEMBER!<
	bgt.b	Leave1
	sub.b	#32,d0			; a -> A, z -> Z
Leave1
	move.b	(a1)+,d2
	cmpi.b	#'a',d2			; uppercase conversion (!)
	blt.b	Leave2			; why?
	cmpi.b	#'z',d2			; Extras!=EXTRAS >REMEMBER!<
	bgt.b	Leave2
	sub.b	#32,d2			; a -> A, z -> Z
Leave2
	cmpi.b	#0,d0			; test new file name end
	beq.s	TestMatch
	cmp.b	d0,d2			; COMPARE names
	beq.s	Compare			; if ONLY one char is wrong -> skip
	bra.s	Count			; doesn't match!
TestMatch
	cmpi.b	#0,d2			; test old file name end
	bne.s	Count			; doesn't match!
Matching
	lea	Erase(pc),a0
	tst.b	(a0)
	beq.s	Count			; previous file NOT erased
	lea	PopUp(pc),a0
	clr.b	(a0)			; requester Pops Up!

Count
	clr.l	d2			; prepare for counting
	move.l	d1,a0			; get file name address (d1)
	lea	FileName(pc),a1
MoveName
	addq.l	#1,d2			; increase counter
	move.b	(a0),(a1)+		; copy file name
	cmpi.b	#0,(a0)+		; in requester structure
	bne.s	MoveName
StoreLen
	lea	NameLen(pc),a0
	move.b	d2,(a0)			; remember char num!
SetUp
	move.l	4,a6			; exec base
	move.l	#38,d0			; Lib Ver$ion
	lea	reqname(pc),a1
	jsr	OpenLibrary(a6)
	lea	reqbase(pc),a1		; PC relative!
	move.l	d0,(a1)
	beq.b	NoReqTools

TestPopUp
	lea	PopUp(pc),a0
	tst.b	(a0)			; IF PopUp!=0...
	beq.s	CallOldDelete		; don't pop up! Call old delete

Menu
	move.l	reqbase(pc),a6		; PopUp==1 pop up!
	lea	Text1(pc),a1
	lea	Text2(pc),a2
	lea	tags(pc),a0
	sub.l	a3,a3
	sub.l	a4,a4
	jsr	rtEZRequestA(a6)
	lea	Choice(pc),a0
	move.l	d0,(a0)
OldChoice
;	cmpi.l	#2,d0
;	beq.b	RestoreOldDelete
	cmpi.l	#1,d0
	beq.b	CallOldDelete
	lea	Erase(pc),a0
	move.b	#0,(a0)			; clear ERASED flag (NOT ERASED!)
CloseReqLib
	move.l	$4.w,a6
	move.l	reqbase(pc),a1
	tst.l	(a1)			; if not opened, don't close! :->
	beq.s	NoReqTools
	jsr	CloseLibrary(a6)
NoReqTools
	movem.l	(a7)+,d0-d7/a0-a6
	addq.l	#4,a7
	rts

;RestoreOldDelete
;	move.l	4,a6
;	move.l	dosbase(pc),a1		; PC relative mode
;	move.l	#-72,a0			; is a MUST here!!!
;	move.l	delete(pc),d0
;	jsr	-420(a6)		; set old Delete()

;	bra	CloseReqLib		; I cut it! Call old Delete()!

CallOldDelete
	movem.l	(a7)+,d0-d7/a0-a6	; we need PURE code!
;dirty	jsr	$00000000		; d0n't do it at home! ]:->
	move.l	#return,-(a7)
	move.l	old,-(a7)
	rts
return	movem.l	d0-d7/a0-a6,-(a7)	; as PURE as we can get
	lea	Erase(pc),a0
	move.b	#1,(a0)			; set ERASED flag
	bra.b	CloseReqLib

PatchedData

Text1	dc.b    "BIG BROTHER IS WATCHIN' YOU",10
	dc.b    "Wizard/GlenzPointS (c) 1994",10
	dc.b	"SAA/GlenzPointS, 1995.",10,10
	dc.b	"Intruder wanna delete:",10
FileName
	ds.b	80
	dc.b	0

Text2	dc.b	"I'll take my risk!|Noooo! I'm innocent!",0
	even

tags	dc.l	$80000000+22,1<<2
	dc.l	0
reqbase	dc.l	0
Choice	dc.l	0			; don't request! Use old choice!
Erase	dc.b	1			; erased flag (first erased!)
NameLen	dc.b	1			; file name length
					; IF !=1 (==0) point will apear!
PopUp	dc.b	0			; IF ==1 pops up
	even
reqname	dc.b	'reqtools.library',0
	

End
