Создание TSR программ в ОС MS DOS, страница 3

Модуль предотвращения повторной установки программы в память объединен с модулем выгрузки программы из памяти. Модуль устанавливается вместо стандартного обработчика прерывания 2Fh. Сама программа будет закреплена за функцией 88h, подфункция 99h. При наличии программы в памяти она будет отзываться на запрос прерывания 2Fh  кодом  0BEBEh, возвращаемом в регистре AX. Выгружать программу из памяти будем тогда, когда в командной строке программы будет задан ключ  /del. При выгрузке из памяти восстанавливаются оригинальные вектора прерываний, освобождается память, занятая самой программой и блоком окружения программы.

Для записи в файл путей запускаемых программ создаем обработчик прерывания 21h, подфункции 4Bh. Эта функция используется DOS при запуске программ, одним из ее аргументов является ASCIIZ строка, в которой прописан путь запускаемого файла. Эту строку мы и выводим в файл, используя функции файлового ввода/вывода прерывания 21h. Если файл не существует, то создается новый, информация дописывается в конец файла. После завершения работы управление передается  оригинальному обработчику прерывания 21h.


Текст программы

.286

CSEG segment

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG

org 100h

Start:

;Переходим на метку инициализации:

jmp   Init

;обработчик функции 4bh 21h прерывания:

New_21h proc

pushf

cli  

cmp   ah,4bh                  ;Проверим: это функция 4bh?

je    Ok_4b             ;Если так, то на метку Ok_4b

;Если нет, перейдем на оригинальный обработчик прерывания 21h.

sti

popf 

jmp   dword ptr cs:[Old_21h]

Ok_4b:

pusha

push ds           ;Сохраним регистры

mov di,ds

mov bp,dx

;Посчитаем длину пути запускаемого файла:

mov si,0

Check_path_len:

mov dx,[bp]       ;загрузим в dx очередную букву из пути файла

cmp dl,0    ;сравниваем символ с 0, т.к. строка заканчивается нулем

je stop

inc bp

inc si            ;счетчик

jmp Check_path_len

stop:

sub bp,si

;Открываем файл, в который будем записывать названия программ:

No_create_error:

mov   AH,3DH

mov   al,2

push cs                ;Адрес строки должен быть в DS:DX

pop   ds

lea   dx,FILE

xor   cx,cx

int   21h

jnc   File_write        ;Если ошибка, то файла скорее всего не существует

;Создадим файл, если его нет:

mov   ah,3Ch           

mov   cx,100010b        ;атрибуты

lea   dx,FILE          

int   21h

jnc   No_create_error   ;если ошибка, перейдем на оригинальный обработчик

pop ds                        ;прерывания 21h.

popa                         

popf

jmp   dword ptr cs:[Old_21h]

Запись пути программ в файл:

File_write:

Mov   BX,AX

mov   ah,42h                  ;дописываем в конец файла

xor   cx,cx

xor   dx,dx

mov   al,2

int   21h

;запись пути

mov   ds,di

lea   dx,[bp]

mov   ah,40h

mov   cx,si

int   21h              

push cs                ;Адрес строки должен быть в DS:DX

pop   ds

lea   dx,new_str

mov   ah,40h                  ;записываем символ перевода строки

mov   cx,1

int   21h

mov   ds,di

;Закрываем файл:

mov   ah,3Eh;

int   21h

pop ds

popa                    ;Восстановим использованные регистры

sti

popf

jmp dword ptr cs:[Old_21h] ;Перейдем на оригинальный обработчик прерывания 21hз

Old_21h dd ? ;Переменная для хранения оригинального адреса обработчика 21h

new_str db 10

FILE db 'C:\files.txt',0      ;имя файла

New_21h endp

New_2F  Proc            ; обработка мультиплексного прерывания

cli              

cmp   ax,8899h          ; обработка мультиплексного прерывания  

jne   exit 

mov ax, 0BEBEh    ; отправляем отзыв

sti