Quelltext /~heha/hs/vcall0.zip/VCALL0.PAS

unit vcall0;
{VCALL0-VxD-Interface}
interface

{Diese Funktion ruft die angegebene Routine im Kernel-Mode auf,
 sofern das VxD VCALL0.386 geladen ist. Andernfalls wird die Routine
 direkt gerufen.
 Die Routine mu FAR codiert und darf nicht verschachtelt sein.
 Sie darf keine bergabeparameter haben, kann aber ein LongInt liefern
 (oder krzere Datentypen). Sie sollte vorzugsweise in Assembler geschrieben
 sein.
 Es drfen keine Routinen in anderen Codesegmenten (m.a.W.: Units) gerufen
 werden. Ebenso mssen Stack-, Range- und Overflow-Checking fr den
 Geltungsbereich der auszufhrenden Routine ausgeschaltet sein, da diese
 genauso ungltige Far-Calls (zur Unit System) generieren.
 Das hngt damit zusammen, da Ringbergnge im Protected Mode ausschlielich
 ber Gates, Traps und IRETs mglich sind.
 12/96: Hinzugefgter Code zum dynamischen Laden des VxD's}
function Call0(Routine:Pointer):LongInt;
function high_freq(hz:LongInt; Routine:Pointer):Boolean;

{Versionsnummer des VxD's einholen, liefert 0, wenn VxD nicht prsent}
function GetVCall0Ver:Word;

{Diese Variable wird beim Initialisieren belegt. Ist sie NIL, ist VCALL0.386
 nicht geladen, und die Routine wird direkt gerufen}
var
 VCall0_Entry: Pointer;

{VxD-ID zu Informationszwecken global}
const
 VCall0_Device_ID=$3A7A;
const
 VxDName:array[0..10]of Char='VCALL0.386'#0;

implementation

function GetVCall0Ver:Word; assembler;
 asm	mov	cx,word ptr VCall0_Entry[2]
	jcxz	@@1		{NIL?}
	mov	ah,0
	call	[VCall0_Entry]
@@1:	end;

function Call0(Routine:Pointer):LongInt; assembler;
 asm	mov	cx,word ptr VCall0_Entry[2]
	jcxz	@@1		{NIL?}
	les	bx,[Routine]
	mov	ah,1		{Funktionsnummer}
	call	[VCall0_Entry]
	jmp	@@2
@@1:
	call	[Routine]
@@2:	end;

function high_freq(hz: LongInt; Routine:Pointer):Boolean; assembler;
 asm	mov	cx,word ptr VCall0_Entry[2]
	stc
	jcxz	@@1		{NIL?}
	db $66; mov dx,word ptr [hz]
	les	bx,[Routine]
	mov	ah,2		{Funktionsnummer}
	call	[VCall0_Entry]
@@1:	mov	al,FALSE
	jc	@@2
	inc	al
@@2:	end;

var
 VXDLDR_Entry:Pointer;
 OldExit:Pointer;

{Deinstallation}
procedure NewExit; far; assembler;
 asm
	db	$66
	mov	ax,word ptr [OldExit]
	db	$66
	mov	word ptr [ExitProc],ax
	mov	ax,$0002	{Unload_VxD}
	mov	bx,VCALL0_Device_ID
	call	[VXDLDR_Entry]
 end;

function Get_VCALL0_Entry:Word; assembler;
 asm	xor	di,di
	mov	es,di
	mov	bx,VCALL0_Device_ID
	mov	ax,$1684	{Get Device API Entry Point}
	int	$2F
	mov	ax,es
	mov	word ptr [VCALL0_Entry],di
	mov	word ptr [VCALL0_Entry+2],ax
 end;

{Initialisierung}
begin
 asm	call	Get_VCALL0_Entry
	or	ax,ax		{<>0?}
	jnz	@@e		{ja, statisch geladen!}
	mov	bx,$0027	{VXDLDR-Device-ID}
	mov	ax,$1684
	int	$2F
	mov	ax,es
	or	ax,ax		{<>0?}
	jz	@@e		{nein, wohl kein Windows95?}
	mov	word ptr [VXDLDR_Entry],di
	mov	word ptr [VXDLDR_Entry+2],ax
	mov	dx,offset VxDName
	mov	ax,$0001	{Load_VxD}
	call	[VXDLDR_Entry]
	jc	@@e		{Fehler!}
	push	cs
	push	offset NewExit
	db	$66
	pop	ax
	db	$66
	xchg	word ptr [ExitProc],ax
	db	$66
	mov	word ptr [OldExit],ax
	call	Get_VCALL0_Entry	{Zweiter Versuch}
@@e: end;
end.
Vorgefundene Kodierung: UTF-80