home *** CD-ROM | disk | FTP | other *** search
- LISTING 3:GETKHA.ASM
- ; GETKHA.ASM - This assembler module is designed to link with a C module
- ; to effect low level getkey hook management.
-
- DGROUP group _DATA,_BSS
-
- _DATA segment word public 'DATA'
-
- extrn _poll0_hook:word ; Tell the assembler that the
- extrn _filter0_hook:word ; hook pointers are actually
- extrn _poll1_hook:word ; declared within the application.
-
- _DATA ends
-
- _BSS segment word public 'BSS'
- _BSS ends
-
- _TEXT segment byte public 'CODE'
- assume cs:_TEXT, ds:DGROUP
-
- ;- I16INTR -------------------------------------------------------------;
- ;
- ; This is the interrupt 16H intercept where the hook processing is done.
- ;
- ; Entry parms: AH is the function selector
- ; Functions 0 and 1 are implemented.
- ; Exit parms: AX is the return data for function 0
- ; For function 1, flags == NZ indicates data available
- ;-----------------------------------------------------------------------;
- i16intr proc far
- cmp ah,0 ; Test the entry value of AH
- je i16f0 ; to decode the function.
- cmp ah,1 ; If management is needed for
- jne $+5 ; function #2, another test must
- jmp i16f1 ; be added here.
- jmp dword ptr cs:[orig16] ; Pass on to the original INT 16H.
- i16f0: ; Save BX and CX since
- push bx ; they will be crashed by
- push cx ; the STK2LOC procedure.
- call stk2loc ; Switch to a local stack.
- push bx ; Save the stack switch flag.
- push si ; Save the original SP and SS.
- push di
- push dx ; Save the other misc registers.
- push es
- push ds
- push bp
- sub sp,2 ; Create local stack storage for
- mov bp,sp ; a word - addressable by [bp].
- i16f0a:
- mov ds,cs:[ds_seg] ; Setup DS addressability and
- push ss ; place the parameter on the stack
- push bp ; as the poll0 hook will expect.
- call ds:[_poll0_hook] ; Call the poll0 hook procedure.
- add sp,4 ; Clean up the stack.
- or ax,ax ; If the hook procedure is
- jnz i16f0b ; asserting data, jmp to i16f0b.
- mov ah,1 ; Otherwise, enter a loop where
- pushf ; the actual keyboard and the
- call cs:[orig16] ; polling hook are repeatedly tested.
- jz i16f0a ; When data is detected from the
- mov ah,0 ; actual keyboard, use INT 16H
- pushf ; function 0 to retrieve it.
- call cs:[orig16]
- mov [bp],ax ; Place the keycode in the stack var.
- i16f0b:
- mov ds,cs:[ds_seg] ; Setup DS addressability and
- push ss ; Place the parameter on the stack
- push bp ; as the filter0 hook will expect.
- call ds:[_filter0_hook] ; Call the filter0 hook procedure.
- add sp,4 ; Clean up the stack.
- or ax,ax ; AX != 0 means that the hook proc
- jnz i16f0a ; absorbed the key so get another.
- mov ax,[bp] ; Else, put the keycode in AX and
- add sp,2 ; prepare to return to the caller.
- pop bp
- pop ds ; Restore registers from the stack.
- pop es
- pop dx
- pop di
- pop si
- pop bx
- call stk2orig ; Change back to the original stack.
- pop cx
- pop bx
- iret
- i16f1: ; Process a function 1 call.
- push ax ; Save AX, BX and CX since
- push bx ; they will be crashed by
- push cx ; the STK2LOC procedure.
- call stk2loc ; Switch to a local stack.
- push bx ; Save the stack switch flag.
- push si ; Save the original SP and SS.
- push di
- push dx ; Save the other misc registers.
- push es
- push ds
- push bp
- mov ds,cs:[ds_seg] ; Setup DS addressability and
- call ds:[_poll1_hook] ; call the poll1 hook procedure.
- pop bp
- pop ds
- pop es
- pop dx ; Restore the registers.
- pop di ; NOTE: the AX register must
- pop si ; not be changed through this
- pop bx ; section.
- call stk2orig ; Switch to the original stack.
- pop cx
- pop bx
- or ax,ax ; If AX != 0 then data is available.
- pop ax
- jz i16f1a
- push bp ; Manipulate the zero flag in the
- mov bp,sp ; flags image on the stack.
- and word ptr [bp+6],not 40h
- pop bp
- iret ; Return to the caller.
- i16f1a:
- jmp cs:[orig16] ; Pass on to the original BIOS when
- i16intr endp ; no data available from a hook.
-
- ;- STK2LOC -------------------------------------------------------------;
- ;
- ; This procedure manages the switch from the stack in effect when an
- ; interrupt 16H call is intercepted by i16intr. In many cases, the
- ; stack in effect will be that of the host OS.
- ;
- ; entry parms: None
- ; exit parms: BX flags whether or not a stack switch was done
- ; DI and SI hold the original SS and SP (when a switch)
- ; AX and CX are crashed
- ;-----------------------------------------------------------------------;
- stk2loc proc near
- pop cx ; Get return address off of stack.
- mov ax,cs ; If CS == SS then this is a
- mov bx,ss ; recursive entry so don't swtich
- cmp ax,bx ; stacks.
- mov bx,0 ; BX is the stack switch flag for
- je s2la ; stk2orig. if BX == 1, a switch
- inc bx ; was done.
- push si ; Using DI and SI to save the
- push di ; original stack segment/pointer
- mov si,sp ; between this procedure and the
- mov di,ss ; stk2orig procedure.
- cli ; Must insure that no interrupts
- mov ss,ax ; occur until the new stack is fully
- mov sp,offset loc_stack ; defined.
- sti
- s2la:
- jmp cx ; Return to the caller.
- stk2loc endp
-
- ;- STK2ORIG ------------------------------------------------------------;
- ;
- ; Restore the original stack that was in effect when the interrupt 16H
- ; call was originally made.
- ;
- ; Entry parms: BX is stack switch flag (from stk2loc)
- ; DI and SI hold the original SS and SP values
- ; Exit parms: CX is crashed
- ;-----------------------------------------------------------------------;
- stk2orig proc near
- pop cx ; Get return address off of stack.
- or bx,bx ; If BX != 0 then a stack switch
- jz s2oa ; was done by stk2loc and must
- cli ; be un-done here.
- mov ss,di ; DI and SI hold the original
- mov sp,si ; SS and SP values.
- sti
- pop di ; Restore these from the original
- pop si ; stack.
- s2oa:
- jmp cx ; Return to the caller
- stk2orig endp
-
- ;- I22INTR -------------------------------------------------------------;
- ;
- ; An intercept of the INT 22H terminate vector saved in the PSP is
- ; used to insure that no matter how the application may terminate,
- ; the INT 16H interrupt vector is reset.
- ;
- ; Entry parms: None
- ; Exit parms: None - all registers must be preserved.
- ;-----------------------------------------------------------------------;
- i22intr proc far
- push ax
- push es
- xor ax,ax ; Set ES to 0 to address vectors.
- mov es,ax
- cli ; No interrupts during vector change.
- mov ax,word ptr cs:[orig16] ; Restore the original INT 16H
- mov es:[16h*4],ax ; vector.
- mov ax,word ptr cs:[orig16+2]
- mov es:[16h*4+2],ax
- sti
- pop es
- pop ax ; Continue with the original
- jmp dword ptr cs:[orig22] ; termination process.
- i22intr endp
-
- ;- I16SETUP ------------------------------------------------------------;
- ;
- ; This procedure should be called one time at the start of the
- ; application to initialize the INT 16H and INT 22H intercept logic.
- ;
- ; Entry parms: None
- ; Exit parms: None
- ;-----------------------------------------------------------------------;
- public _i16setup
- _i16setup proc near
- mov cs:[ds_seg],ds ; Save the caller's DS value for
- mov ax,3516h ; later uses when calling hooks.
- int 21h ; Read the current INT 16H vector
- mov word ptr cs:[orig16],bx ; and store in orig16.
- mov word ptr cs:[orig16+2],es
- push ds
- push cs
- pop ds ; Make the INT 16H vector point
- mov dx,offset i16intr ; to the intercept routine.
- mov ax,2516h
- int 21h
- pop ds
- mov ah,51h ; The original terminate vector
- int 21h ; is stored within the PSP.
- mov es,bx ; INT 21H, function 51H will return
- cli ; the current PSP segment in BX
- mov ax,es:[0ah] ; Use this to modify the vector.
- mov word ptr cs:[orig22],ax
- mov ax,es:[0ch]
- mov word ptr cs:[orig22+2],ax
- mov word ptr es:[0ah],offset i22intr
- mov es:[0ch],cs
- ret ; Done with the initialization.
- _i16setup endp
-
- ds_seg dw ? ; the DS value expected by hook procedures
- orig16 dd ? ; original contents of the INT 16H vector
- orig22 dd ?; ; original contents of the INT 22H vector
-
- ; A local stack is maintained for use by the INT 16H intercept logic.
- ; This stack is in effect when hook procedures are called. It may
- ; need to be enlarged if significant procedure nesting or recursion
- ; will occur.
-
- dw 512 dup(?)
- loc_stack label byte
-
- _TEXT ends
- end