This DPMI 0.9 Specification is hosted by Tenberry Software, Inc.

11.4 Allocate Real Mode Call-Back Address


[Next Section] * [Previous Section] * [DPMI Index]
[Tenberry Home] * [Software Quality] * [DOS/4G] * [DOS/4GW] * [DOS/16M]

This service is used to obtain a unique real mode SEG:OFFSET that will transfer control from real mode to a protected mode procedure.

At times it is necessary to hook a real mode interrupt or device call-back in a protected mode driver. For example, many mouse drivers call an address whenever the mouse is moved. Software running in protected mode can use a real mode call-back to intercept the mouse driver calls.

To Call

     AX = 0303h
     DS:(E)SI = Selector:Offset of procedure to call
     ES:(E)DI = Selector:Offset of real mode call structure

Returns

     If function was successful:
     Carry flag is clear.
     CX:DX = Segment:Offset of real mode call address

     If function was not successful:
     Carry flag is set.

Call-Back Procedure Parameters

     Interrupts disabled
     DS:(E)SI = Selector:Offset of real mode SS:SP
     ES:(E)DI = Selector:Offset of real mode call structure
     SS:(E)SP = Locked protected mode API stack
     All other registers undefined

Return from Call-Back Procedure

     Execute an IRET to return
     ES:(E)DI = Selector:Offset of real mode call structure
          to restore (see note)

Programmer's Notes

Example Code

The following code is a sample of a real mode interrupt hook. It hooks the DOS Int 21h and returns an error for the delete file function (AH=41h). Other calls are passed through to DOS. This example is somewhat silly but it demonstrates the techniques used to hook a real mode interrupt. Note that since DOS calls are reflected from protected mode to real mode, the following code will intercept all DOS calls from both real mode and protected mode.

     ;******************************************************
     ; This procedure gets the current Int 21h real mode
     ; Seg:Offset, allocates a real mode call-back address,
     ; and sets the real mode Int 21h vector to the call-
     ; back address.
     ;******************************************************
     Initialization_Code:
     ;
     ; Create a code segment alias to save data in
     ;
             mov     ax, 000Ah
             mov     bx, cs
             int     31h
             jc      ERROR
             mov     ds, ax
             ASSUMES DS,_TEXT
     ;
     ; Get current Int 21h real mode SEG:OFFSET
     ;
             mov     ax, 0200h
             mov     bl, 21h
             int     31h
             jc      ERROR
             mov     [Orig_Real_Seg], cx
             mov     [Orig_Real_Offset], dx
     ;
     ; Allocate a real mode call-back
     ;
             mov     ax, 0303h
             push    ds
             mov     bx, cs
             mov     ds, bx
             mov     si, OFFSET My_Int_21_Hook
             pop     es
             mov     di, OFFSET My_Real_Mode_Call_Struc
             int     31h
             jc      ERROR
     ;
     ; Hook real mode int 21h with the call-back address
     ;
             mov     ax, 0201h
             mov     bl, 21h
             int     31h
             jc      ERROR

     ;******************************************************
     ;
     ; This is the actual Int 21h hook code.  It will return
     ; an "access denied" error for all calls made in real
     ; mode to delete a file.  Other calls will be passed
     ; through to DOS.
     ;
     ; ENTRY:
     ;    DS:SI -> Real mode SS:SP
     ;    ES:DI -> Real mode call structure
     ;    Interrupts disabled
     ;
     ; EXIT:
     ;    ES:DI -> Real mode call structure
     ;
     ;******************************************************

     My_Int_21_Hook:
             cmp     es:[di.RealMode_AH], 41h
             jne     Chain_To_DOS
     ;
     ; This is a delete file call (AH=41h).  Simulate an
     ; iret on the real mode stack, set the real mode
     ; carry flag, and set the real mode AX to 5 to indicate
     ; an access denied error.
     ;
             cld
             lodsw                   ; Get real mode ret IP
             mov     es:[di.RealMode_IP], ax
             lodsw                   ; Get real mode ret CS
             mov     es:[di.RealMode_CS], ax
             lodsw                   ; Get real mode flags
             or      ax, 1           ; Set carry flag
             mov     es:[di.RealMode_Flags], ax
             add     es:[di.RealMode_SP], 6
             mov     es:[di.RealMode_AX], 5
             jmp     My_Hook_Exit
     ;
     ; Chain to original Int 21h vector by replacing the
     ; real mode CS:IP with the original Seg:Offset.
     ;
     Chain_To_DOS:
             mov     ax, cs:[Orig_Real_Seg]
             mov     es:[di.RealMode_CS], ax
             mov     ax, cs:[Orig_Real_Offset]
             mov     es:[di.RealMode_IP], ax

     My_Hook_Exit:
             iret

[Next Section] * [Previous Section] * [DPMI Index]
[Tenberry Home] * [Software Quality] * [DOS/4G] * [DOS/4GW] * [DOS/16M]
This HTML edition of the DPMI 0.9 Specification is hosted by Tenberry Software, Inc., makers of the DOS/16M and the DOS/4G family of DOS extenders. Page last modified 2003.1.28, <webmaster@tenberry.com>