Программирование Базы данных
| |
В этом разделе,
как и в следующем, мы не будем ничего
говорить о защищённом режиме работы
процессора. Мы рассмотрим здесь некоторые
особенности, которые необходимо учитывать
при разработке резидентных программ и
драйверов, работающих совместно с WINDOWS. Очень часто резидентные
программы или драйверы перехватывают
аппаратное прерывание клавиатуры и
отслеживают коды нажимаемых клавиш,
выполняя те или иные действия при нажатии
заданных комбинаций. Например, драйвер "секретного"
диска Norton DISKREET может при нажатии заданной
комбинации клавиш блокировать доступ к "секретному"
диску, экрану и клавиатуре. Так как WINDOWS в расширенном
режиме использует собственную систему
клавиатурного ввода/вывода, основанную на
очередях сообщений, а также реализует
концепцию виртуальных машин, нажатие
активизирующих резидентную программу
комбинаций клавиш в неподходящий момент
может не привести к желаемому результату и
даже стать причиной "зависания"
системы. Есть два возможных решения
этой проблемы. Во-первых, можно запретить
запуск WINDOWS, если активна резидентная
программа или драйвер, не способные
работать совместно с WINDOWS. Во-вторых, на
время работы WINDOWS можно запретить
выполнение резидентной программой или
драйвером специфических функций,
несовместимых с WINDOWS (например, запретить
активизацию резидентной программы при
нажатии комбинации клавиш). Перед запуском WINDOWS и перед
её завершением вызываются функции
прерывания INT 2Fh 1605h и 1606h соответственно.
Ваша резидентная программа или драйвер
могут подготовить собственные обработчики
для этих прерываний и отслеживать моменты
запуска WINDOWS и завершения её работы. Функция 1605h вызывается при
запуске WINDOWS: Регистры при вызове
прерывания:
AX 1605h
ES:BX 0000h:0000h
DS:SI 0000h:0000h
CX 0000h
DX Флаги:
Бит 0 = 0, если выполняется
инициализация WINDOWS в
расширенном режиме;
Бит 0 = 1, если выполняется
инициализация DOS-экстендера
"Microsoft 286 DOS extender"
(используется
в стандартном режиме работы WINDOWS);
Биты 1-15 зарезервированы, их
содержимое неопределено.
Регистры перед
возвратом из прерывания:
CX 0000h,
если WINDOWS может продолжать инициализацию;
CX <> 0, если запуск WINDOWS недопустим.
Функция 1606h
вызывается при завершении WINDOWS расширенном
или стандартном режиме: Регистры при вызове
прерывания:
AX 1606h
DX Флаги:
Бит 0 = 0, если выполняется завершение
WINDOWS,
работавшей в расширенном режиме;
Бит 0 = 1, если выполняется завершение
DOS-экстендера
"Microsoft 286 DOS extender";
Биты 1-15 зарезервированы, их
содержимое не определено.
Обработчик
функции 1605h может выполнить необходимые
действия, связанные с модификацией
алгоритма работы резидентной программы или
драйвера, а также при помощи
соответствующей установки регистра CX может
разрешить или запретить запуск WINDOWS. Обработчик функции 1606h
получает управление при завершении работы
WINDOWS и может восстановить прежний алгоритм
работы критичной к WINDOWS резидентной
программы или драйвера. Приведённая ниже
резидентная программа перехватывает
прерывание INT 2Fh и отслеживает функции 1605h
и 1606h, вызывая сообщение и ожидая нажатия на
любую клавишу при запуске и завершении
работы WINDOWS:
Листинг 22.
Контроль запуска WINDOWS
Файл wintsr.asm
-----------------------------------------------------------
.MODEL tiny
.CODE
.STARTUP
jmp begin
old_int2Fh_off dw 0 ; Адрес старого обработчика
old_int2Fh_seg dw 0 ; прерывания 2Fh
; Сообщение, которое будет выдано на экран
; при запуске WINDOWS
msg_win db 'WINDOWS Started. Press any key...$'
msg_win_off dw offset msg_win
; Сообщение, которое будет выдано на экран
; при завершении WINDOWS
msg_win1 db 'WINDOWS Ended. Press any key...$'
msg_winend_off dw offset msg_win1
; Новый обработчик прерывания 2Fh нужен
; для проверки наличия программы в памяти
; при ее запуске для предохранения
; от повторного запуска
new_int2Fh proc far
cmp ax,0FF00h
jz
installed
cmp ax,1605h
jz
winstart
cmp ax,1606h
jz
winend
jmp dword ptr
cs:old_int2Fh_off
winstart: ; запуск WINDOWS
push ax
push bx
push cx
push dx
push ds
mov
dx,cs:msg_win_off
mov ah,9
push cs
pop ds
int 21h
mov ax,0
int 16h
pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr
cs:old_int2Fh_off
winend: ; завершение WINDOWS
push ax
push bx
push cx
push dx
push ds
mov
dx,cs:msg_winend_off
mov ah,9
push cs
pop ds
int 21h
mov ax,0
int 16h
pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr
cs:old_int2Fh_off
; Если код функции 0FF00h, то возвращаем
; в регистре AX значение 00FFh. Это признак
; того, что программа уже загружена в память
installed:
mov ax,00FFh
iret
new_int2Fh endp
;==============================
; Точка входа в программу
; В этом месте начинается выполнение
программы
begin proc
; Проверяем, не загружена ли уже программа
; в память
mov ax,0FF00h
int 2Fh
cmp ax,00FFh
jne
first_start
mov dx,offset
msg_load1
mov ah,9
int 21h
.EXIT
; Первоначальный запуск программы
first_start:
; Запоминаем адрес старого обработчика
прерывания 2Fh
mov ax,352Fh
int 21h
mov
cs:old_int2Fh_off,bx
mov
cs:old_int2Fh_seg,es
push cs
pop ds
; Выводим сообщение
mov dx,offset
msg_load
mov
ah,9
int 21h
mov dx,OFFSET
new_int2Fh
mov ax,252Fh
int 21h
; Завершаем программу и оставляем
резидентно
; в памяти часть программы, содержащую новые
; обработчики прерываний
mov dx,OFFSET
begin
int 27h
begin endp
msg_load db 'Резидентная программа WINTSR
загружена$'
msg_load1 db 'Резидентная программа WINTSR
уже загружена$'
end
Следующая
резидентная программа работает аналогично,
но она запрещает запуск WINDOWS. Попробуйте,
запустив предварительно программу NOWINTSR,
запустить WINDOWS и посмотрите, что из этого
получится.
Листинг 23. Запрет
запуска WINDOWS
Файл nowintsr.asm
-----------------------------------------------------------
.MODEL tiny
.CODE
.STARTUP
jmp begin
old_int2Fh_off dw 0 ; Адрес старого обработчика
old_int2Fh_seg dw 0 ; прерывания 2Fh
; Сообщение, которое выдаётся при запуске
WINDOWS
msg_win db 'NOWINTSR несовместима с'
'WINDOWS.
Нажмите любую клавишу...$'
msg_win_off dw offset msg_win
; Сообщение, которое выдаётся при
завершении WINDOWS
msg_win1 db 10,13,'WINDOWS Ended. Press any key...$'
msg_winend_off dw offset msg_win1
; Новый обработчик прерывания 2Fh нужен
; для проверки наличия программы в памяти
; при ее запуске для предохранения
; от повторного запуска
new_int2Fh proc far
cmp ax,0FF00h
jz
installed
cmp ax,1605h
jz
winstart
cmp ax,1606h
jz
winend
jmp dword ptr
cs:old_int2Fh_off
winstart:
push ax
push bx
push cx
push dx
push ds
mov
dx,cs:msg_win_off
mov ah,9
push cs
pop ds
int 21h
mov ax,0
int 16h
pop ds
pop dx
pop cx
pop bx
pop ax
mov cx,0ffh
jmp dword ptr
cs:old_int2Fh_off
winend:
push ax
push bx
push cx
push dx
push ds
mov
dx,cs:msg_winend_off
mov ah,9
push cs
pop ds
int 21h
mov ax,0
int 16h
pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr
cs:old_int2Fh_off
; Если код функции 0FF00h, то возвращаем
; в регистре AX значение 00FFh. Это признак
; того, что программа уже загружена в память
installed:
mov ax,00FFh
iret
new_int2Fh endp
;==============================
; Точка входа в программу
begin proc
; Проверяем, не загружена ли уже программа
; в память
mov ax,0FF00h
int 2Fh
cmp ax,00FFh
jne
first_start
mov dx,offset
msg_load1
mov ah,9
int 21h
.EXIT
; Первоначальный запуск программы
first_start:
; Запоминаем адрес старого обработчика
прерывания 2Fh
mov ax,352Fh
int 21h
mov
cs:old_int2Fh_off,bx
mov
cs:old_int2Fh_seg,es
push cs
pop ds
; Выводим сообщение
mov dx,offset
msg_load
mov
ah,9
int 21h
mov dx,OFFSET
new_int2Fh
mov ax,252Fh
int 21h
; Завершаем программу и оставляем
резидентно
; в памяти часть программы, содержащую новые
; обработчики прерываний
mov dx,OFFSET
begin
int 27h
begin endp
msg_load db 'Резидентная программа
NOWINTSR загружена$'
msg_load1 db 'Резидентная программа NOWINTSR
уже загружена$'
end
[ << Назад ] [ Содержание ] [ Далее >> ]
|