windows-nt/Source/XPSP1/NT/base/mvdm/wow16/user/winhook.asm
2020-09-26 16:20:57 +08:00

135 lines
3 KiB
NASM

title WINHOOK.ASM - SetWindowsHook() and friends
ifdef WOW
NOEXTERNS equ 1
SEGNAME equ <TEXT>
endif
.xlist
include user.inc
.list
swappro = 0
; include NEW_SEG1 struc used in GetProcModule
include newexe.inc
ExternFP <GetCodeInfo>
ExternFP <GetExePtr>
ExternFP <GetCurrentTask>
ExternFP <SetWindowsHookInternal>
createSeg _%SEGNAME,%SEGNAME,WORD,PUBLIC,CODE
createSeg _DATA,DATA,WORD,PUBLIC,DATA,DGROUP
defgrp DGROUP,DATA
;===========================================================================
sBegin %SEGNAME
assumes CS,%SEGNAME
assumes DS,DATA
assumes ES,NOTHING
;============================================================================
;
; HANDLE FAR PASCAL GetProcModule(FARPROC lpfn);
;
; This function returns the module handle corresponding to a given
; hook proc address.
;
; CAUTION: This uses the undocumented feature of "GetCodeInfo()" that it
; returns the module handle in ES register.
;
cProc GetProcModule, <PUBLIC, FAR>
ParmD lpfn
LocalV seginfofromkernel, %size NEW_SEG1+2
cBegin
; Turns out GetCodeInfo
;
pushd lpfn ; GetCodeInfo(lpfn, &seginfo)
lea ax,seginfofromkernel
push ss
push ax
call GetCodeInfo
or ax,ax ; AX is BOOL fSuccess (even though windows.h says void)
mov ax,es ; ES contains the module handle according
; to David Weise...
jnz gpmexit ; We're ok
; hack. Excel global allocs some memory, puts
; code into it and passes it to us. The GetCodeInfo fails in this
; case so we need to get the module handle for a globalalloced
; chunk of memory.
push word ptr lpfn+2
call GetExePtr
gpmexit:
ifdef DEBUG
or ax,ax
jnz gpm900
DebugErr DBF_ERROR, "Invalid Hook Proc Addr"
xor ax,ax
gpm900:
endif
cEnd
;==============================================================================
;
; FARPROC FAR PASCAL SetWindowsHook(int idHook, FARPROC lpfn)
; {
; SetWindowsHookEx2(idHook,
; (HOOKPROC)lpfn,
; GetProcModule(lpfn),
; (idHook == WH_MSGFILTER ? GetCurrentTask() : NULL));
; }
;
cProc ISetWindowsHook,<FAR, PUBLIC, LOADDS>
ParmW idHook
ParmD lpfn
LocalW hmodule
LocalW htask
cBegin
; Check if some apps are trying to unhook a hook using SetWindowsHook()
mov bx, seg_lpfn
cmp bx, HHOOK_MAGIC
jz swhHookMagic
cmp idHook,WH_MSGFILTER
jnz swh10
call GetCurrentTask
jmp swhMakeCall
swhHookMagic:
; Now, it is clear that this app wants to unhook by calling SetWindowsHook()
; All Micrographix apps do this trick to unhook their keyboard hooks.
; Fix for Bug #7972 -- SANKAR -- 05/30/91 --
; Let us unhook the node passed in thro lpfn;
ifdef DEBUG
DebugErr <DBF_WARNING>, "SetWindowsHook called to unhook: use UnhookWindowsHook"
endif
xor ax,ax
jmps swhMakeCall
swh10:
pushd lpfn
call GetProcModule
swhMakeCall:
push ax
push idHook
pushd lpfn
call SetWindowsHookInternal
swhExit:
cEnd
sEnd %SEGNAME
END