Source file: /~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 kürzere Datentypen). Sie sollte vorzugsweise in Assembler geschrieben
 sein.
 Es dürfen keine Routinen in anderen Codesegmenten (m.a.W.: Units) gerufen
 werden. Ebenso müssen Stack-, Range- und Overflow-Checking für den
 Geltungsbereich der auszuführenden Routine ausgeschaltet sein, da diese
 genauso ungültige Far-Calls (zur Unit System) generieren.
 Das hängt damit zusammen, daß Ringübergänge im Protected Mode ausschließlich
 über Gates, Traps und IRETs möglich sind.
 12/96: Hinzugefügter 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 präsent}
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.
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded