4.8.4. Поиск файлов

Найти нужный файл на диске намного сложнее, чем просто открыть      - для

этого требуются две функции при работе с короткими именами (найти первый

файл и найти следующий файл) и три - при работе с длинными именами в DOS 7.0

(найти первый файл, найти следующий файл, прекратить поиск).

Функция DOS     Найти первый файл Вход:  АН = 4Eh

AL используется при обращении к функции APPEND СХ = атрибуты, которые должен иметь файл (биты О (только для чте­ния) и 5 (архивный бит) игнорируются. Если бит З (метка тома)

установлен, все остальные биты игнорируются) DS:DX   адрес с именем файла, которое может включать

путь и маски для поиска (символы * и ?) Выход:  CF = 0 и область DTA заполняется данными, если файл найден

CF = 1 и АХ = 02h, если файл не найден; ОЗЬІесли путь не найден; 12h,

если неправильный режим доступа

Вызов этой функции заполняет данными область памяти DTA (область переда­чи данных), которая начинается по умолчанию со смещения от блока данных PSP (при запуске СОМ- и сегменты DS и ES содержат сег-

ментный адрес начала PSP), но ее можно переопределить с помощью функции 1 Ah.

Функция DOS 1Ah: Установить область DTA Вход:    АН = lAh

DS:DX = адрес начала DTA (128-байтный буфер)

Функции поиска файлов заполняют DTA следующим образом: " +00h: байт     - биты 0-6: ASCII-код буквы диска

бит 7: диск сетевой

+0Ш:   11 байт - маска поиска (без пути) +0Ch: байт     - атрибуты для поиска +0Dh: слово   - порядковый номер файла в директории +OFh: слово   - номер кластера начала внешней директории +1Ш: 4 байта — зарезервировано + 15h: байт     - атрибут найденного файла

+ 16h: слово - время создания файла в формате DOS:

биты 15-11: час (0-23)

биты 1О-5: минута

биты 4-0: номер секунды, деленный на 2 (0-30)слово  - дата создания файла в формате DOS:

биты 15-9: год, начиная с 1980

биты 8-5: месяц

биты 4-0: день +lAh: 4 байта - размер файла

+lEh: 13 байт - ASCIZ-имя найденного файла с расширением

После того как DTA заполнена данными, для продолжения поиска следует

вызывать функцию 4Fh, пока не будет возвращена ошибка.

Функция DOS 4Fh: Найти следующий файл Вход:    АН = 4Fh

DTA - содержит данные от предыдущего вызова функции   Eh или Выход: CF = 0 и DTA содержит данные о следующем найденном файле, если не

произошла ошибка CF = 1 и АХ = код ошибки, если произошла ошибка

В случае с длинными именами файлов (LFN) применяется набор из трех подфункций функции DOS        которые можно использовать, только если запущен

IFSmgr (всегда запускается при обычной установке Windows 95, но не запускает­ся, например, с загрузочной дискеты MS DOS 7.0).

Функция LFN4Eh: Найти первый файл с длинным именем Вход:    АХ - 714Eh

CL = атрибуты, которые файл может иметь (биты 0 и 5 игнорируются)

СН = атрибуты, которые файл должен иметь

SI = 0: использовать Windows-формат даты/времени SI = 1: использовать DOS-формат даты/времени DS:DX = адрес ASCIZ-строки с маской для поиска (может включать * и    Для совместимости маска *.* ищет все файлы в директо­рии, а не только файлы, содержащие точку в имени) ES:DI - адрес 318-байтного буфера для информации о файле Выход: CF = О

АХ - поисковый идентификатор СХ = Unicode-флаг:

бит 0: длинное имя содержит подчеркивания вместо непреобразу-

емых Unicode-символов бит   короткое имя содержит подчеркивания вместо непреобразу-емых Unicode-символов CF = 1, АХ = код ошибки, если произошла ошибка (7100h - функция

не поддерживается)

Если файл, подходящий под маску и атрибуты поиска, найден, область дан­ных по адресу ES:DI заполняется следующим образом:

+00h: 4 байта - атрибуты файла

биты 0-6: атрибуты файла DOS

бит 8: временный файл

+04Ь: 8 байт - время создания файла

+0СЬ: 8 байт - время последнего доступа к файлу

+14Ь: 8 байт - время последней модификации файла

+1СЬ: 4 байта - старшее двойное слово длины файла

+20Ь: 4 байта - младшее двойное слово длины файла

+24п: 8 байт - зарезервировано

+2Сп: 260 байт - АБСК-имя файла длинное

+130Б: 14 байт - АБСК-имя файла короткое

Причем даты создания/доступа/модификации записываются в одном; из двух форматов, в соответствии со значением при вызове функции. Щпёоте-формат -64-битное число 100-наносекундных интервалов с 1 января 1601 года; если исполь­зуется БОБ-формат - в старшее двойное ' слово записывается БОБ-дата, а в млад­шее - БОБ-время.

Функция іт4Яі: Найти следующий файл Вход:    АХ - 714Ні

ВХ - поисковый идентификатор (от функции 4ЕЬ)

= формат даты/времени Е8:Б1 = адрес буфера для информации о файле Выход: СЕ - 0 и СХ = Шісосіе-флаг, если следующий файл найден

СЕ = 1, АХ = код ошибки, если произошла ошибка (7100І1 - функция

Функция LFNA 1h: Закончить поиск файла Вход:    АХ = 71Alh

ВХ = поисковый идентификатор Выход: CF °= 0, если операция выполнена

CF = 1 и АХ = код ошибки, если произошла ошибка (7100h — функция не поддерживается)

В качестве примера, использующего многие функции работы с файлами, рас­смотрим программу, заменяющую русские буквы Н латинскими Н во всех фай­лах с расширением .ТХТ в текущей директории (такая замена требуется для каж­дого текста, пересылающегося через сеть Fidonet, программное обеспечение

которой воспринимает русскую букву Н как управляющий символ).

; fidoh.asm

; .Заменяет русские "Н" латинскими "Н" во всех файлах с расширением .'ТХТ ; в текущей директории.

.model tiny

не поддерживается)

. code

org 100h

; СОМ-файл

start:

xor

mov

ah,4Eh cx, cx

;   Поиск первого файла.

;  Не системный,  не директория и т. д.

;  Маска для поиска в Г^БХ

mov

filespecттт

file_open:

int 21h

jc no_more_files

mov ax,3D02h

mov dx,80h+1Eh

int 21h ■

jc not_open

mov bx.ax

mov cx,l

mov    ■ dx,offset buffer

read next:

mov int jc

dec

js cmp

jne

mov

mov

dec dec

mov

int

mov inc inc mov int jmp

find next:

not_open:

ah,3Fh 21h •

find.next

ax

find_next

byte ptr buffer, 8Dh

read_next

byte ptr buffer, 48h

ax,4201h

cx

cx

dx,cx

21h

ah,40h

cx

cx

dx,offset buffer 21h

short read_next

ah,3Eh

21h

ab,4Fh

dx,80h"

short file_open

mov

int

mov mov jmp

no_more_files:

ret

filespec db "..txf.O

buffer label byte

end start

Если CF

1

файлы кончились.

Открыть файл для чтения и записи. Смещение БТА + смещение имени файла от начала БТА.

Если файл не открылся - перейти к следующему.

Идентификатор файла в ВХ. Считывать один байт. Начало буфера - в ОХ.

Чтение файла:

Если ошибка - перейти к следующему. Если АХ = 0 - файл кончился -перейти к следующему. Если не считана русская

считать следующий байт. Иначе - записать в буфер латинскую букву "Н".

Переместить указатель позиции назад на 1. СХ = ОЕЕЕЕп, БХ = ОЕЕЕЕІ1.

Записать в файл.

Один байт (СХ = 1) из буфера в ОЭ^Х.

Считать следующий байт.

Закрыть предыдущий файл.

Найти следующий файл.

Смещение БТА от начала РБР. Если файлы кончились,

выйти из программы.. .

Маска для поиска.

Буфер для чтения/записи -

за концом программы.

файла от текущей