Source file: /~heha/hs/dos/dirhide.zip/DIRHIDE.ASM

;hoffentlich QEMM-kompatibel
;DIRHIDE versteckt "versteckte" Verzeichnisse
	include	prolog.asm
REQfunc		equ	4b46h		;in AX
REQcode		equ	9877h		;in DX
ANScode		equ	8766h		;in AX; DX=Segmentadresse
ResPara		equ	(ISRBase-PSPOrg+ISRE-ISRA+0fh)/16

		org	5ch
ctrl0		db	?		;Ein/Aus-Schalter
		;Bit7: global ein/aus
		;Bit6: DIR e/a
		;Bit5: FILE e/a
ISRBase:	;FCB's überschreiben
		org	100h
		print	Text0		;Meldung
		mov	[ctrl0],0c0h	;erst mal Standard laden
		call	InstChk		;ggf. ES auf Fremdroutine
		;nun ch=Statusregister:
		;Bit0: Deinstallation nicht möglich
		;Bit7: Noch nicht installiert
		mov	si,81h
		cld
scancl:		lodsb
		call	Upcase
		cmp	al,'?'
		je	help
		cmp	al,'U'
		je	UnInst
		cmp	al,'D'
		je	DisActiv
		cmp	al,'H'
		je	help
		cmp	al,'F'
		je	File
		cmp	al,'S'
		JN	z,Status	;'n tolles Makro erspart JUMPS
		cmp	al,0dh
		jne	scancl
		jmp	Install

setfile:	or	[es:ctrl0],20h
		jr	scancl
resfile:	and	[es:ctrl0],not 20h
		jr	scancl
setdir:		or	[es:ctrl0],40h
		jr	scancl
resdir:		and	[es:ctrl0],not 40h
		jr	scancl
File:	;Schalter für versteckte Dateien
		lodsb
		cmp	al,'+'
		jz	setfile
		cmp	al,'-'
		jz	resfile		;sonst Hilfeseite
help:	;Hilfe Option "H" oder "?"
		mov	dx,offset TextH
		jr	TXTO1

UnInst:	;Deinstallation(sversuch) Option "U"
		mov	dx,offset Text5
		test	ch,80h
		jnz	TXTO1		;Wenn nicht nötig!
		or	ch,ch
		jz	Raus
		PRINT	Text4
		mov	dx,offset Text4a
disab:		and	[es:Ctrl0],not 80h	;löschen
		jmp	TXTOut
DisActiv:;Deaktivieren Option "D" oder Dirs ein/aus mit D+/D-
		lodsb
		cmp	al,'+'
		jz	SetDir
		cmp	al,'-'
		jz	ResDir
		test	ch,80h		;Schon installiert?
		mov	dx,ofs Text5
		jnz	TXTO1
		mov	dx,ofs Text4
		jr	disab
	;Deinstallation
Raus:		lds	dx,[es:ofs OldInt21-ISRA+ISRBASE]
		DOS	2521h
		DOS	49h		;den Speicher ab es freigeben
		push	cs
		pop	ds
		mov	dx,ofs Text3	;removed...
TXTO1:		jmp	TXTOut

InstChk:;Installationscheck, ES=Zeiger auf installierte Routine oder n.a.!,
	;Bit7(CH)=0: Installationscheck erfolgreich, dann:
	;ES: Segmentadresse der residenten Routine
	;Bit0(CH)=0: Zeiger nicht von anderen verbogen
		mov	ax,REQfunc	;eigentlich Cursorform ermitteln
		mov	dx,REQcode
		int	21h
		xor	ch,ch
		cmp	ax,ANScode	;gleich?
		jz	T21I
		or	ch,80h		;Z-Flag "retten"
		mov	dx,ds
T21I:		push	dx		;Segment der TSR
	;Segment retten
		DOS	3521h		;Get Int21
		SES	<OldInt21>,bx
		cmp	bx,ofs NewInt21-ISRA+ISRBASE
		jnz	T21FLT
		mov	bx,es
		cmp	bx,dx
		je	T21OK
T21FLT:		inc	ch		;ch <>0 wenn andere TSR stört
T21OK:		pop	es
		ret

Install:	test	ch,80h
		mov	dx,ofs Text2	;"reaktiviert"
		jz	setab
	;ISR nach vorn schaufeln
		cld
		push	cs
		pop	es
		mov	si,ofs ISRA
		mov	di,ofs ISRBase
		mov	cx,(ISRE-ISRA)/2
		rep	movsw
	;Zeiger verbiegen
		mov	dx,ofs NewInt21-ISRA+ISRBASE
		DOS	2521h			;Set Int21
	;Environment freigeben
		mov	es,[2ch]	;Segment Environment
		DOS	49h		;ENV-Speicher ab es freigeben
	;Test des Hochladens
		mov	ax,cs
		mov	es,ax		;Eigenes Programm=Resident!
		cmp	ax,0a000h
		jc	NoHi		;unten
		PRINT	Text1a
NoHi:		mov	dx,offset Text1
	;VB enabeln
setab:		or	[es:Ctrl0],80h	;setzen
	;dx-adressierten Text ausgeben
TXTOut:		DOS	9		;Textausgabe
	;Programm beenden
LFOut:		push	dx
		PRINT	_NL
		pop	dx
		cmp	dx,ofs Text1	;Installierung? (etwas seltsam!)
		mov	ax,4C00h
		jnz	exi
		mov	ah,31h		;Resident
		mov	dx,ResPara
exi:		int	21h

Status:		test	ch,80h
		mov	dx,ofs Text5	;"Noch nicht installiert"
		jnz	TXTOut
		PRINT	TextS1		;"Status d"
		mov	cl,[es:ctrl0]
		test	cl,80h
		mov	dx,ofs Text4+1	;"eaktiviert"
		jz	TXTOut
		test	cl,40h
		call	WRPM		;PlusMinus
		PRINT	TextS2
		test	cl,20h		;PlusMinus
		call	WRPM
		jr	LFOut		;nur Zeilenende
WRPM:	;Plus (Z=0) oder Minus (Z=1) ausgeben
		mov	dl,'+'
		jnz	wrpm1
		mov	dl,'-'
wrpm1:		DOS	2
		ret
		_UPCASE
ISRA:
NewInt21:	;Neue INT21-Routine
		pushf
		cmp	ax,REQfunc      ;Installationscheck?
		jne	I21cont
		cmp	dx,REQcode
		jne	I21cont
		mov	ax,ANScode
		mov	dx,cs
		popf
		iret
I21cont:
		test	[cs:ctrl0],80h
		jz	isrend
		cmp	ah,4eh          ;FindFirst?
		je	hid
		cmp     ah,4fh          ;FindNext?
		je      hid
		cmp	ah,11h		;FindFirst FCB
		je	fcb
		cmp	ah,12h		;FindNext FCB
		je	fcb
isrend:		popf
		JMPF			;jmp far
OldInt21	dd	?

hid1:           mov     ah,4fh          ;FindNext
hid:
		popf
		pushf
		call	[cs:OldInt21+(ISRBase-ISRA)]
					;FindFirst bzw. FindNext
		jc      hide
		pushf
		push    ax bx es
		DOS     2fh             ;GetDTA
		mov     al,[es:bx+15h]
		call	ChkHid
		pop     es bx ax
		jnz	hid1		;wenn's klingelt
		popf
hide:		sti
		retf    2

fcb1:           mov     ah,12h          ;FindNext
		pushf
fcb:
		popf
		pushf
		sti
		call	[cs:OldInt21+(ISRBase-ISRA)]
					;FindFirst bzw. FindNext
		cli
		cmp	al,0ffh		;Fehler?
		jz	fcb5		;ja!
		push    ax bx es
		DOS	2fh		;Get DTA
		mov	al,[es:bx]
		add	al,1
		sbb	al,al
		jz	fcb2		;Wenn kein extendet FCB
		mov	al,[es:bx+13h]	;Attribut
		call	ChkHid		;testet Attribut
		sti
		jz	fcb2
;	pushf
;	push cx dx
;	vid 0e07h
;	pop dx cx
;	popf
fcb2:		pop     es bx ax
		jnz	fcb1		;wenn's klingelt
fcb5:		iret			;zum IRET

ChkHid:	;PE: AL=Attributbyte
	;PA: Z=0 wenn geheim
	test	al,2
	jz	hid2
	test	al,10h
	jz	hid3		;Ist eine Datei
	test	[cs:Ctrl0],40h	;Ist ein Verzeichnis
	jr	hid2
hid3:	test	[cs:Ctrl0],20h
hid2:	ret
ISRE:

Text0	db	'DirHide 1.1 (haftmann#software): $'
Text1a	db	'hoch$'
Text1	db	'geladen, Speicherbedarf '
	dcd	%((ResPara)*16+16)
	db	' Bytes.$'
Text2	db	'reaktiviert.$'
Text3	db	'vom Speicher entfernt.$'
Text4	db	'deaktiviert.$'
Text4a	db	' (Andere TSR stahl Int21)$'
Text5	db	'Noch nicht installiert!$'
TextS1	db	'Status d$'
TextS2	db	' f$'
TextH	db	'		++ FREEWARE ++',nl
	db	'Programm zum wirklichen Verstecken von "hidden" Dirs und Files.',nl,10
	db	'Parameter:	- (keiner)	TSR laden oder aktivieren',nl
	db	'		- h oder ?	diese Hilfe',nl
	db	'		- d		DirHide deaktivieren',nl
	db	'		- d{+|-}	Dirs verstecken E/A, Vorgabe EIN',nl
	db	'		- f{+|-}	Files verstecken E/A, Vorgabe AUS',nl
	db	'		- s		Statusinfo',nl
	db	'		- u		TSR entfernen$'
_NL	db	nl,'$'

	endc
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded