📄 hooks.asm
字号:
done_save_regs:
cmp cs:ignore_intenter_checks,0 ;see safety_flush above
jne dont_check_istatus
call interrupt_status_ok ;got this from MSDOS
jc commit_done ;excyclopedia,ralphl
dont_check_istatus:
cld ;clear direction for all
;the guys in commit!
cmp cs:commit_all_when_ok,0
jnz commit_all_behind
les di,cs:accessing_swap_file_ptr
test es:[di].enhanced_mode_flags,WRITE_IS_PENDING
jnz commit_done
or es:[di].enhanced_mode_flags,THIS_WRITE_IS_LAZY
call Commit_LRU_Dirty_Element ;write out a dirty block!
les di,cs:accessing_swap_file_ptr
and es:[di].enhanced_mode_flags,NOT THIS_WRITE_IS_LAZY
commit_done:
cmp cs:processor_type,CPU386
jae restore386regs
pop di ;restore registers...
pop si
pop bp
pop es
pop dx
pop cx
pop bx
pop ax
pop ds
done_restore_regs:
mov ss,cs:save_stack_ss ;restore stack
mov sp,cs:save_stack_sp
critical_section_out:
push ax ;turn off the disk critical
mov ax,8101h ;section--ok to context
int 2ah ;switch now
pop ax
exit_08_no_crit:
dec cs:in_bambi
push ds ;set the indos flag
push di ;so TSRS wont try to
lds di,cs:indosaddr ;pop up while we are
dec byte ptr ds:[di] ;doing write behind
pop di ;re-enter us via int 21
pop ds
ret
save386regs:
;WARNING 386 code only runs on a 386!
.386
pushad
push fs
push gs
push ds
push es
jmp short done_save_regs
restore386regs:
pop es
pop ds
pop gs
pop fs
popad
jmp short done_restore_regs
.8086
commit_all_behind:
cmp cs:reboot_when_ok,0
je not_reboot
call shut_down_pop_up
not_reboot:
call commit_all_dirty
cmp cs:invalidate_when_ok,0
je do_not_invalidate
mov cs:num_valid_buffers,0 ; invalidate supercache
call flush_queue
mov cs:invalidate_when_ok,0
do_not_invalidate:
cmp cs:reboot_when_ok,0
je just_commit
call rebootsystem
;;no fall through!
just_commit:
mov cs:commit_all_when_ok,0
jmp short commit_done
write_behind_cache endp
;
;int08hook
;FUNCTION
; hardware timer interrupt 08h handler.
; processes the timer interrupt by calling older handlers (one will
; do the EOI)
;
; If a while has passes since the last try, do some write-behind
;USES
; none
;
int08hook proc far
pushf ;set up iret frame
cli ;in case of bad software
call DWORD PTR cs:int08chain ;call int 08 handler chain
inc cs:num_ticks_to_int28
dec cs:num_ticks_to_timeout ;'nuf time passed to do
jz check_dump ;write behind?
no_action:
iret ;if not, just exit
check_dump:
cmp cs:number_of_dirty_elements,0 ;timeout period begins when
jz restart_timeout ;dirty blocks exist
;;; we should't re-enter the DOS bios on timer ticks
;;; so we need to check that here. We don't put the check
;;; in write_behind since there are times we will want to
;;; write behind when indos is set.
push ds ;set the indos flag
push di ;so TSRS wont try to
lds di,cs:indosaddr ;pop up while we are
cmp byte ptr ds:[di],0
pop di ;re-enter us via int 21
pop ds
jne no_action
sti ;allow interrupts through
;during write behind
;dirty blocks are timed out
call write_behind_cache ;so do a write-behind
mov cs:num_ticks_to_timeout,1 ;1 so next tick decs to zero
;so write-behind will continue
;until there are no more
;dirty blocks
jmp short no_action ;exit
restart_timeout:
;no dirty blocks so restart
;timeout period
mov cs:num_ticks_to_timeout,5*18 ;BUG BUG hard coded
jmp short no_action
int08hook endp
;int10hook
;FUNCTION
; keep track of entry count on ROM BIOS video functions
; flag used to prevent write-behind during video bios operations
;USES
; none
int10hook proc far
pushf ;set up iret frame
inc cs:in_10 ;entering int10h
cli ;safetyfirst
call cs:int10chain ;allow call through chain
dec cs:in_10 ;exiting int10h
iret ;exit to caller
int10hook endp
;int13hook
;FUNCTION
; keep track of entry count on ROM BIOS disk functions
; handle special case where applications do disk IO directly
; by comming cache before operations
; via int 13 (quite rare, but case must be handled)
;USES
; none
;
int13hook proc far
;;;the next 8 instructions are basically a PUSHF
;;;that maintains the input flags (interrupt flag)
push ax ;reserve area for flags
push bp ;preserve bp
push ax ;preserve ax
mov bp,sp ;get base pointer to stack
mov ax,ss:[bp+10] ;get user input flags->ax
mov ss:[bp+4],ax ;put user input flags into
;reserved area
pop ax ;restore ax
pop bp ;restore bp
; pushf ;iret frame with input flags
cmp cs:in_bambi,0 ;bambi called device driver?
je flush_before_13 ;get all data to disk!
continue_13:
inc cs:in_13 ;normal entry of int13
cli ;safety first
call cs:int13chain ;call int13 chain
pushf ;preserve flags on return!
dec cs:in_13 ;normal exit of int13
popf ;restore int13 return flags
retf 2 ;exit with current flags
;iret
flush_before_13:
push es
push di
les di,cs:accessing_swap_file_ptr
cmp byte ptr es:[di],0
pop di
pop es
jne continue_13
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
continue_write_int13:
mov cs:commit_all_when_ok,1
mov cs:invalidate_when_ok,1
call safety_flush
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp short continue_13 ;go do the int 13 request
int13hook endp
biosdataoffset dw 40h
;int09hook
;FUNCTION
; keyboard interrupt handler keeps track of entry and exit to
; keyboard handling routines
;
int09hook proc far
pushf ;iret frame with input flags
cli
cmp cs:number_of_dirty_elements,0
jne check_ctrlaltdel
continue_09:
inc cs:in_09 ;entry to int09h
call cs:int09chain ;do the int09 chaing
dec cs:in_09 ;exit of int09h
iret
check_ctrlaltdel:
push ax
push es
mov es, word ptr cs:biosdataoffset
mov al, byte ptr es:[17h] ; bios location of keyboard state and status flags
test al, KP_ALT
jz not_alted_in9
test al, KP_CTRL
not_alted_in9:
jnz ctrl_alt_down
popesaxandcontinue_09:
pop es
pop ax
;;;zero flag not set if ctrl+alt are down
jmp short continue_09
ctrl_alt_down:
push ax
in al,60h ; put scan code into al
cmp al,SC_DEL ;delete key?
pop ax
jne popesaxandcontinue_09
and byte ptr es:[17h],NOT KP_CTRL
pop es
pop ax
inc cs:in_09 ;entry to int09h
call cs:int09chain ;do the int09 chain
dec cs:in_09 ;exit of int09h
mov cs:commit_all_when_ok,1
mov cs:reboot_when_ok,1
push es
mov es,word ptr cs:biosdataoffset
or byte ptr es:[17h],KP_CTRL
pop es
;the following may finish off the write behind and reboot the system,
;however it will not if in_bambi is set
;the next timer tick will do this too however
call write_behind_cache
iret
int09hook endp
;int19hook
;FUNCTION
; flush the cache before rebooting machine!
;
int19hook proc far
cmp cs:in_bambi,0
jne dont_commit19
call commit_all_dirty
dont_commit19:
jmp dword ptr cs:int19chain
int19hook endp
;int15hook
;FUNCTION
; flush the cache before rebooting machine!
; based on code from emm386
int15hook proc far
cmp ah,4fh ;keyboard intercept?
je check_keys
chain15:
jmp dword ptr cs:int15chain
check_keys:
cmp al,SC_DEL
jne chain15
push ax
push es
mov ax, 40h
mov es, ax
mov al, byte ptr es:[17h] ; bios location of keyboard state and status flags
test al, KP_ALT
jz not_alted
test al, KP_CTRL
not_alted:
pop es
pop ax
jz chain15
cmp cs:reboot_when_ok,0
jne already_shutting_down ;don't race when we reboot!
mov cs:reboot_when_ok,1
mov cs:commit_all_when_ok,1
call write_behind_cache
already_shutting_down:
jmp short chain15
int15hook endp
int25isstupid dw ?
;int25hook
;FUNCTION
; flush and invalidate the cache before and after absolute
; disk read. This is for BONEHEADED Central Point Software's
; brain-damaged disk detection code from hell. Also, it
; makes disk de-fragmenters safe.
;
int25hook proc far
;;;the next 8 instructions are basically a PUSHF
;;;that maintains the input flags (interrupt flag)
push ax ;reserve area for flags
push bp ;preserve bp
push ax ;preserve ax
mov bp,sp ;get base pointer to stack
mov ax,ss:[bp+10] ;get user input flags->ax
mov ss:[bp+4],ax ;put user input flags into
;reserved area
pop ax ;restore ax
pop bp ;restore bp
; pushf ;iret frame with input flags
mov cs:commit_all_when_ok,1
mov cs:invalidate_when_ok,1
call safety_flush
cli
call dword ptr cs:int25chain
pop cs:int25isstupid
pushf
jnc noresetbads
mov cs:next_bad_entry_ptr,0 ;nortons will return error correctly
mov cs:num_bad_blocks,0 ;but we don't want to think first block
;is bad when its ok
noresetbads:
mov cs:commit_all_when_ok,1
mov cs:invalidate_when_ok,1
call safety_flush
popf
retf ;no 2 since this is int 25
int25hook endp
;int26hook
;FUNCTION
; flush and invalidate the cache before and after absolute
; disk write. This is for BONEHEADED Central Point Software's
; brain-damaged disk detection code from hell. Also, it
; makes disk de-fragmenters safe.
;
int26hook proc far
;;;the next 8 instructions are basically a PUSHF
;;;that maintains the input flags (interrupt flag)
push ax ;reserve area for flags
push bp ;preserve bp
push ax ;preserve ax
mov bp,sp ;get base pointer to stack
mov ax,ss:[bp+10] ;get user input flags->ax
mov ss:[bp+4],ax ;put user input flags into
;reserved area
pop ax ;restore ax
pop bp ;restore bp
; pushf ;iret frame with input flags
mov cs:commit_all_when_ok,1
mov cs:invalidate_when_ok,1
call safety_flush
cli
call dword ptr cs:int26chain
pop cs:int25isstupid
pushf
mov cs:commit_all_when_ok,1
mov cs:invalidate_when_ok,1
call safety_flush
popf
retf ;no 2 since this is int 26
int26hook endp
align 2
dw 64 dup ('!') ;11-11-92 scottq
dw 128 dup ('!') ;stack for write-behind
temp_res_stack dw 128 dup ('!')
resident_stack dw 0
public resident_stack
public temp_res_stack
zseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -