Сборник по задачам и примерам Assembler

Установка звуковой карты ремонт компьютеров митино подарки в честь 8 марта|eams search


Работа с файлами в MS DOS (длинные имена)

Перечисленные выше функции работают в различных версиях «чистой» системы MS DOS, вплоть до версии 6.22 включительно. Операционные системы Windows 95/98/Mil также поддерживают свою версию MS DOS, которая имеет номер 7.0. Операционная система Windows 95/98/Mil организует для программ MS DOS специальную среду для работы, называемую сеансом DOS. Система MS DOS 7.0, будучи созданной для работы в среде Windows 95/98/Mil, имеет в своем составе средства для работы с файловой системой Windows. Эта файловая система, как известно, отличается тем, что полное имя файла может достигать длины 255 символов. MS DOS 7.0 также умеет работать с длинными именами файлов. В данном разделе мы рассмотрим предназначенные для работы с файловой системой Windows средства среды MS DOS, работающей под управлением
Windows.
Определить факт того, в какой системе работает программа, можно по результатам работы функций 30h — получить версию DOS (прерывания 21п) и 4аЗЗп (прерывания 2fh).
Вход: АН = 30h; AL = определяет значение, возвращаемое в ВН: 00h— OEM-номер (как для DOS 2.0-4.0x);01h — номер версии.
Выход: AL = главный номер версии; АН - младший номер версии; BL:CX = 24-битный серийный номер пользователя (необязательно).


:prg07_19.a$m - программа демонстрации определения факта того. ;в какой системе работает программа.
.code
;.....определим номер версии ОС MS DOS
mov al .00
movah.30h ;номер функции DOS
int21h ;А1-главный номер версии. АН-младший номер версии
]с exit ;переход в случае ошибки

В регистрах AL и АН возвращаются главный и младший номера версии MS DOS. При функционировании под Windows эти номера равны 07h и Oah соответственно. Задание значения AL = 01 дает такой же эффект.

:prg07_20.asm - программа демонстрации определения факта работы в среде MS DOS 7.0.
.code
:-----определить факт работы в среде MS DOS 7.0
movax.4a33h ;номер функции DOS int 2fh
cmp ax, 0
jneexit ;переход, если работа не в среде MS DOS 7.0

Последняя функция возвращает 0 для MS DOS версии 7.0 и выше. Установить факт того, что система поддерживает длинные имена файлов, можно вызовом функции 71a0h прерывания 21п — получить информацию о томе. Если она возвращает ошибку (CF = 1), то текущая файловая система не поддерживает длинных имен файлов. Для вызова этой функции необходимо указать корневой каталог тома, о котором необходимо получить информацию. Вход: АХ = 71A0h; DS:SI — ASCIZ-имя корневого каталога тома, о котором необходимо получить информацию (например, "С:\"); ES:DI — буфер для имени файловой системы; СХ ¦= размер буфера, адрес которого задан в ES: DI (32 байта).
Выход: CF = 0 в случае успеха, следующие регистры установлены: ВХ = флаги файловой системы: 0 — при поиске учитывать регистр букв в именах файлов; 1 — сохранять регистр букв в элементах каталога; 2 — использование символов Unicode в именах каталогов и файлов; 3-13 — резерв (0); 14 — поддержка DOS-функций для длинных имен файлов; 15 — сжатый том; СХ = максимальная длина файловых имен (обычно 255); DX = максимальная длина пути (обычно 260); ES: DI — в буфере по этому адресу ASCIZ-имя файловой системы, например "FAT", "FAT32", "NTFS", "CDFS"; CF = 1 в случае неудачи, при этом АХ = код ошибки или AX=7100h, если функция не поддерживается.
В Windows 95/98 появились дополнительные возможности как самой файловой системы, так и средств по ее управлению. Основное нововведение — поддержка длинных имен файлов. Основа файловой системы та же — таблица разрешения файлов FAT, но любой файл в этой системе имеет два имени — длинное имя и его псевдоним, который соответствует формату 8.3. Данный псевдоним создается системой Windows 95/98 автоматически.
Нужно правильно понимать различие в способах использования длинных имен файлов в приложениях MS DOS и Win32. Приложения MS DOS получают до-ступ к длинным именам файлов с помощью дополнительных функций прерывания 21h. Приложения Windows используют для этого соответствующие функции API.
Длинное имя файла представляет собой ASCIIZ-строку длиной до 255 символов. Система формирует псевдоним для этого имени форматом 8.3 в соответствии со следующим правилом: берутся первые 6 символов длинного имени, после них добавляется символ тильда (-), за тильдой ставится некий порядковый номер. Для первого имени формата 8.3 это 1. Если такой псевдоним уже существует, то порядковый номер очередного псевдонима будет на 1 больше. Расширение псевдонима формируется из первых трех символов расширения длинного имени (если оно существует). Если похожих имен много, то номер в псевдониме может быть двузначным, при этом первая (символьная) часть псевдонима сокращается
до 5 символов, и т. д.
Рассмотренные выше функции MS DOS для работы с файлами и каталогами не поддерживают длинных имен. Для этого система Windows 95/98 предоставляет приложениям MS DOS аналогичные функции, но имеющие другие номера. Впрочем, при внимательном рассмотрении большинства из этих номеров, видно, какой из старых функций они соответствуют. Новые номера состоят из четырех цифр: первые две — 071h, последние две — номер старой функции. Для некоторых функций существуют особенности в их работе. Так, для поиска файлов по-прежнему используются две функции (по новой нумерации — 714eh и 714fh) прерывания 21h. Новые функции теперь возвращают информацию о файлах через специальную структуру WI N32_F INDDATA, адрес которой возвращается в качестве
результата их работы.
При работе с функциями, поддерживающими длинные имена файлов, используются еще две структуры: by handle_f 11 e_information и filetime. Назначение структуры by_hand1e_file_iinformation и работу с ней мы рассмотрим при обсуждении функции MS DOS 71a6h. Структура filetime содержит 64-разрядное значение, которое определяет число 100-наносекундных интервалов, прошедших с 12:00 утра 1 января 1901 года.

FILETIME Struc
DwLowDateTime dd ? :младшие 32 бита значения времени DwHighDateTime dd ? хтаршие 32 бита значения времени FILETIME ends

Теперь приведем перечень функций прерывания 21h, работающих с файлами, которые имеют длинные имена. Для удобства дальнейшего рассмотрения в следующей таблице приведены соответствующие функции API WIN32 и «старые» функции прерывания 21h.

Новая
функция int 21h
Старая функция int 21h
Назначение
Функция API Win32
5704h
Получить дату и время последнего доступа
GetFileTime
5705h
Установить дату и время
SetFileTime
последнего доступа
5706h
Получить дату и время создания
GetFileTime
5707h
Установить дату и время создания
SetFileTime
7139h
39h
Создать каталог
CreateDirectory
713Ah
3ah
Удалить каталог
RemoveDirectory
713Bh
3bh
Изменить текущий каталог
SetCurrentDi rectory
7141h
41h
Удалить файл
DeleteFile
7143h
43h
Получить или установить
GetFileAttributes,
атрибуты файла
SetFileAttributes
7147h
47h
Получить текущий каталог
GetCurrentDirectory
714Eh
4Eh
Найти первый файл
FindFirstFile
714Fh
4Fh
Найти следующий файл
FindNextFile
7156h
56h
Переименовать файл
MoveFile
7160h
Получить полный путь
GetFullPathName
7160h
Получить полный путь
GetShortPathName
с-краткими именами
7160h
Получить полный путь
Отсутствует
с длинными именами
716Ch
3ch, 3dh, 5bh
Создать или открыть файл
CreateFile, OpenFile
71A0h
Получить информацию о томе
GetVolumelnfonnati on
71Alh
Завершить поиск
FindClose
71A6h
Получить информацию о файле
GetFi1 elnformationByHandle
по описателю
71A7h
Преобразовать время файла
Fi1eTi meToDOSDateTime
в DOS-время
71A7h
Преобразовать DOS-время во время файла
00SDateTi meToFi1eTi me
71A8h
Создать псевдоним
Отсутствует
71A9h
Создать или открыть файл
Отсутствует
на сервере
71AAh
Провести подмену
Отсутствует
71AAh
Отменить подмену
Отсутствует
71AAh
Получить информацию
Отсутствует
о подмене

Рассмотрим наиболее интересные в контексте нашего изложения функции этой таблицы. Информацию по остальным функциям можно получить, в частности, из MSDN. Порядок рассмотрения будет от простых функций к сложным, так как это было в предыдущем разделе, посвященном функциям работы с файлами ДО DOS, имеющими короткие имена.

Создание, открытие, закрытие и удаление файла

функции MS DOS, поддерживающие длинные имена файлов, имеют номера из четырех цифр — первые две равны 71h, последние две соответствуют номеру аналогичной старой функции MS DOS. В программах старые и новые функции применяются вместе по принципу: там, где функция должна работать непосредственно с длинными именами файлов и каталогов, применяются новые функции; там, где функция работает с дескриптором файла, используются старые функции. Новые функции также используются для реализации новых возможностей по работе с файловой системой.

Открытие или создание файла

Для создания или открытия файла с длинным именем используется функция 716Ch (создать или открыть файл). Эта функция аналогична функции 6ch, которая появилась в последних версиях MS DOS (DOS 4.0+). Мы уже обсуждали ее в разделе, посвященном функциям работы с файлами с короткими именами.
Вход: АХ = 716Ch; BX = режимы доступа и флаги:
режим доступа: 0000h — файл только для чтения; 0001h — файл только для записи; 0002h — файл для чтения и записи; 0003h — резерв; 0004п — открыть файл для чтения без изменения даты последнего доступа к файлу; режим разделения: 0000h — режим эмуляции — файл можно открывать любой программе любое количество раз; 00Wh — файл открыт в монопольном режиме доступа; 0020h — файл открыт в монопольном режиме доступа по записи; 0030h — файл открыт в монопольном режиме доступа по чтению; 0040И — открыть файл, разрешая другим процессам доступ по чтению-записи, но с запретом режима эмуляции; флаги: 0080h — дочерний процесс не наследует дескриптор файла, его при необходимости нужно передавать явно; Ol00h — не использовать буферизацию или кэширование средствами ОС, операции чтения-записи выполняются напрямую с диском в соответствии с текущим положением файлового указателя; 0200h — файл нельзя сжимать; 0400h — содержимое регистра 01 следует использовать как порядковый номер в псевдониме файла; 2000h — не вызвать обработчик критической ошибки (int 24h), MS DOS вернет программе код ошибки; 4000h — после каждой операции записи MS DOS будет отправлять данные на диск без их кэширования; СХ - атрибуты создаваемого (и только) файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004п — системный файл; 0008h — метка тома; 0020h — архивный
файл;
DX ~ действия, если файл существует или не существует, значения битов: 00lOh — вернуть ошибку, если файл существует, иначе создать файл; 0001h — открыть файл, если он существует, иначе вернуть ошибку;

0002h — открыть файл без сохранения существующего, иначе вернуть ошибку (если файл не существует); DS:SI — ASCIZ-имя файла;
DI — порядковый номер, который добавляется к концу имени в псевдониме файла (для этого должен быть задан флаг 0400h в регистре ВХ) Номер будет десятичным письмом, то есть если DI=0010h, то конец псевдонима -----16.
Выход: CF=0 — успешное выполнение функции: АХ = дескриптор файла, СХ = состояние: 1 — файл открыт; 2 — файл создан и открыт; 2 — файл открыт без сохранения содержимого существующего файла; CF=1: AX = код ошибки.
После того как файл открыт или создан функцией 716ch, с ним можно работать, используя старые функции чтения-записи и позиционирования. Следующий фрагмент программы показывает вариант применения функции 716Ch.
Закрытие файла производится функцией 3Eh, которая использовалась для файловых функций MS DOS с короткими именами.

Удаление файла

Удаление файлов, имеющих длинные имена, производится функцией 7141h прерывания 21п. Имя файла может быть задано с использованием символов шаблона * и ?, при этом в результате работы функции будут удалены все файлы, чье имя удовлетворяет заданному шаблону.

Получить дату и время создания файла

Вход: АХ = 5706h; ВХ - дескриптор файла. ; . М
Выход: CF = 0 — успешное выполнение функции: СХ = биты установлены следующим образом: 0..4 - секунды, деленные на 2; 5..10 = минуты 0..59; 11..15 -часы; DX - биты установлены следующим образом: 0..4 = день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15 = число лет начиная с 1980 года; SI - двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199; CF = 1: АХ = код ошибки.
Данная функция реализована в полном объеме.

Установить дату последней модификации файла

Вход: АХ = 5705И; ВХ = дескриптор файла; СХ = 0000h; DX - биты установлены следующим образом: 0..4 - день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15- число лет, начиная с 1980 года.
Выход: CF = 0 — успешное выполнение функции; CF = 1: АХ код ошибки.

Аналогично функции 5704h данная функция позволяет установить только дату создания файла.

Установить дату и время создания или последней модификации файла

Вход: АХ = 5707h; ВХ = дескриптор файла; СХ - биты установлены следующим образом: 0..4 - секунды, деленные на 2; 5..10 = минуты 0..59; 11..15 - часы; DX " биты установлены следующим образом: 0..4 = день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15 = число лет начиная с
1980 года;
SI - двоичное значение количества 10-миллисекундных интервалов, добавляемых к времени MS DOS в диапазоне 0..199.
Выход: CF = 0 — успешное выполнение функции; CF = 1: АХ - код ошибки.

Данная функция реализована в полном объеме.
Кроме дополнительных функций для работы с различными временными характеристиками файла Windows-версия MS DOS содержит две функции для преобразования форматов времени. Дело в том, что Windows работает со временем в 64 разрядном формате. При этом точкой отсчета является 00 часов 00 минут 1 января 1601 года. Значение времени содержит число 100-наносекундных интервалов, прошедших с этой даты. По расчетам разработчиков этого значения должно хватить на 400 лет. Для того чтобы манипулировать этим 64-разрядным «средневековьем» с целью представления его в виде, воспринимаемом человеком (DOS-время), введена функция 71a7h.
Вход: АХ = 71a7h; BL = 0 — преобразовать 64-разрядное время в DOS-время; DS:SI = указатель на экземпляр структуры FILETIME, содержащей 64-битное значение времени.
Выход: CF = 0 — успешное выполнение функции, при этом регистры устанавливаются следующим образом: ВН = число 10-миллисекундных интервалов, добавляемых к времени MS DOS (значение в диапазоне 0..199); СХ - время в упакованном формате со значением бит: 0..4 — секунды, деленные на 2; 5..10 — минуты в диапазоне 0..59; 0..4 — часы в диапазоне 0..23; DX = дата в упакованном формате со значением бит: 0..4 — день месяца в диапазоне 1.31; 5..8 — месяц в диапазоне 1..12; 9..15 — число лет начиная с 1980 года (для получения истинного значения прибавьте 1980); CF = 1: АХ - код ошибки. (Структура filetime описывается в программе следующим образом:

FILETIME struc
DwLowOateTime dd ? :младшие 32 бита значения времени
DwHighDateTime dd ? :старшие 32 бита значения времени
FILETIME ends

Вход: АХ = 71a7h; BL - 1 — преобразовать DOS-время в 64-разрядное время; ВН = число 10-миллисекундных интервалов, добавляемых ко времени MS DOS (значение в диапазоне 0..199); СХ = время в упакованном формате со значением бит: 0..4 — секунды, деленные на 2; 5..10 — минуты в диапазоне 0..59; 0..4 — часы в диапазоне 0..23; DX - дата в упакованном формате со значением бит: 0..4 — день месяца в диапазоне 1..31; 5..8 — месяц в диа пазоне 1..12; 9..15 — число лет начиная с 1980 года (для получения истинного значения прибавьте 1980) DS:SI = указатель на экземпляр структуры FILETIME, в которой вернется 64-битное значение времени.
Выход: CF=O — успешное выполнение функции, при этом в области памяти, адресуемой DS:SI, возвращается 64-битное значение времени; CF=1: AX - код ошибки.

Получить атрибуты файла

Вход: АХ ¦ 7143h; BX = действие:
0 -- получить атрибуты, на выходе СХ = атрибуты файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004И — системный файл; 0008h — метка тома; 00lOh — каталог; 0020h — архивный файл;
2 — получить размер сжатого файла — на выходе DX:AX = размер сжатого файла в байтах на диске;
4 — получить дату и время последней записи — на выходе; СХ = время в формате: 0..4 = секунды, деленные на 2; 5.. 10 = минуты (0..59); 11..15 = часы(0..23);
DI дата в формате: 0..4 = день месяца (1..31); 5..8 = месяц (1..12); 9..15 = число лет с 1980 года;
6 — получить дату последнего доступа — на выходе: DI = дата в формате (см. ВХ = 4);
8 — получить дату и время создания — на выходе СХ - время в формате, DI - дата в формате (см. ВХ « 4), SI = двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199;
DS:DX — ASCIZ-строка с именем (путем) файла.
Выход: CF = 0 в случае успеха, информация в регистрах определяется значением ВХ на входе (см. выше):
АХ = код ошибки (CF = 1): 1 — неверное значение в AL; 2 — файл не найден; 3 — несуществующий путь; 5 — доступ запрещен.

Установить атрибуты файла

Вход: АХ = 7143h; ВХ = действие:
1 — установить атрибуты на входе СХ = атрибуты файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004h — системный файл; 0020h — архивный файл; 3 — установить дату и время последней записи: СХ = время в формате: 0..4 " секунды, деленные на 2; 5..10 = минуты (0..59); П..15 - часы (0..23); 01 = дата в формате: 0..4 = день месяца (1..31); 5..8 = месяц (Т.. 12); 9..15 =" число лет с 1980 года;
5 — установить дату последнего доступа (см. ВХ = 3); 7 — установить дату и время создания: СХ = время в формате (см. ВХ - 3), DI = дата в формате (см. ВХ = 3), SI = двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199; DS:DX — ASCIZ-строка с именем (путем) файла.
Выход: CF = о — СХ = слово атрибутов файла; CF=1 — АХ=код ошибки: 1 — неверное значение в AL; 2 — файл не найден; 3 — несуществующий путь; 5 — до-ступ запрещен.

Переименовать файл

Вход: АН = 7156h; DS:DX — ASCIZ-имя существующего файла; ES:O1
имя нового файла; CL - маска атрибутов. Выход: CF = 0 — при успешном переименовании; CF = 1 — АХ = код ошибки: 2 —
файл не найден; 3 — несуществующий путь; 5 — доступ запрещен;
устройства для старого и нового файлов не совпадают.

Работа с дисками, каталогами и организация поиска файлов

Получить информацию о томе

Вход: АН = 71A0h; DS:DX — адрес ASCIZ-строки с именем корневого каталога диска, о котором необходимо получить информацию (С:\); ES:DI — адрес буфера, в который будет помещена ASCIZ-строка с именем файловой системы; СХ = размер буфера, в который будет помещена ASCIZ-строка с именем файловой системы.
Выход: CF = 0 — успешное выполнение, при этом в буфер по адресу в ES-.DI помешается ASCIZ-строка с именем файловой системы и устанавливаются следующие регистры: ВХ =* флаги файловой системы (комбинация значений: 0001 — при поиске учитывается регистр букв в именах файлов; 0002 — файловая система сохраняет регистр букв в элементах каталога; 0004 — использование символов Unicode в именах каталогов и файлов; 4000 — файловая система поддерживает длинные имена файлов и функции для работы с ними; 8000 — том сжат); СХ = максимально допустимая длина имени файла на данном томе без последнего нулевого символа (до 255); DX = максимально допустимая длина пути для данного тома, включая последний нулевой символ (до 260); ;1. _ .,

Создание каталога

Вход: АН = 7139h; DS:DX — адрес строки с ASCIZ-именем существующего файла. Выход: CF = 0 — при успешном переименовании; CF = 1 — АХ = код ошибки: 3 — несуществующий путь; 5 — доступ запрещен.
Удаление каталога
Удаляемый каталог должен быть пуст.
Вход: АН = 713Ah; DS:DX — ASCIZ-строка пути к удаляемому каталогу. Выход: CF = 0 — АХ = не определен; CF = 1 — АХ = код ошибки: 3 — несуществующий путь; 5 — доступ запрещен; 10h — попытка удаления текущего каталога.

Изменить текущий каталог

Понятие текущего каталога аналогично тому, что приводилось выше при рассмотрении функций для работы с файлами, имеющими короткие имена.
АН = 713Bh; DS:DX — указатель на буфер, содержащий полный путь от кор. невого каталога в виде ASCIZ-строки и в качестве последнего элемента включающий имя нового текущего каталога (естественно, что допустимы длинные имена с ограничениями по максимальной длине (см. функцию 71a0h)). Выход: CF = 0 — АХ - не определен; CF=0 — АХ = код ошибки: 03h — путь не найден

Получение текущего каталога

Вход: АН = 7147h; DL - номер устройства (00h = текущее (заданное по умолчанию), 01h = А: И т. д.); DS:SI — указатель на буфер для записи полного пути от корневого к текущему каталогу (длина буфера должна быть не менее длины, возвращаемой в регистре DX функцией 71a0h). Выход: CF = 0 — успешное выполнение функции, в результате чего полный путь от корневого каталога в виде ASCIZ-строки без имени диска и символа \ записывается в буфер, адрес которого указан в DS:SI; АХ - код ошибки (CF = 1): OFh — недопустимый дисковод. Среди новых функций, работающих в том числе с длинными именами файлов, существует функция 7160h, позволяющая получить полные пути для указанных файлов или относительных путей: получить полный путь (сх = 0), получить полный путь с краткими именами (сх = 1), получить полный путь с длинными именами (сх = 2).

Получить полный путь

Вход: АН = 7160h; CL = 0; СН — содержимое результата (СН = 80 — получить имя диска; СН = 0 — получить полный путь); DS:SI — адрес ASCIIZ-строки с именем файла или каталога, для которых необходимо получить полный путь. Допускаются оба типа имен — длинные и короткие; ES:DI — адрес строки, в которую необходимо записать полный путь. Размер буфера должен быть достаточным для размещения пути максимальной длины (функция 71a0h).
Выход: CF = 0 — успешное выполнение функции, в результате чего полный путь от корневого каталога в виде ASCIZ-строки записывается в буфер, адрес которого указан в ES:DI; CF = 1 — АХ = код ошибки.

;prg07_24.asm - программа демонстрации применения функции 7160h (CL=0) прерывания 21h для получения полного пути.
.data
filename db 'my_file with long name.txt'.O
point_fname dd filename
PathFull db 260 dup (0)
point Path dd PalhFull
.code
Ids si .pointfname:формируем указатель на имя файла
les di,point_Path Нормируем указатель на буфер для полного пути

mcvax.7l60h ;номер функции DOS
movch,80h :CH=80h - получить имя : диска; СН=0 - получить полный путь
movCL.O ;получить полный путь
int 21h
jc exit

Данная функция работает очень принмитивно — при указании имени файла или относительного пути (с символами *«.» и «..») она не проверяет его существование, а лишь добавляет к нему имя тсекущего диска и каталога. Поэтому при использовании этой функции требуютсяя другие средства, позволяющие контролировать реальное наличие файла или шути на диске.

Получить полный путь с краткими именами (в формате 8.3)

Вход: АН = 7160h; CL = 1; СН — содержимоое результата (СН = 80 — получить имя диска; СН = 0 — получить полный путь); DS:SI — адрес ASCIIZ-строки с именем файла или каталога, для ксоторых необходимо получить путь в короткой форме. Допускаются оба . типа имен — длинные и короткие: ES:DI — адрес строки, в которую необходцимо записать полный путь. Размер буфера должен быть достаточным длят размещения пути максимальной длины
(функция 71a0h).
Выход: CF = 0 — успешное выполнение функции, в результате чего полный путь от корневого каталога в виде /ASCIZ-строки записывается в буфер, адрес которого указан в ES: DI; CF ' = 1 — АХ = код ошибки.

:prg07_25.asm - программа демонстрации применения функции 7160h (CL=1) прерывания 21h для получения полного путии с краткими именами (в формате 8.3)
filename db 'my_file with lorg name.:.txt' .0
point_fname dd filename
PathFUll db 260 аир (О)
pointjath dd PathFull
* Ids si .pointjfname формирует указатель на имя файла lesdi.point_Path сформируем учазатель на буфер для полного пути movax.7160h :номер функции DOS
movch.80h ;CH»80h - попучить « имя диска; СН=0 - получить полный путь
movCL.l :получить пспный пууть с краткими именами

На выходе функция формирует стрроку, содержащую полный путь, причем все I Длинные компоненты этого пути замееняются их краткими псевдонимами, удовлетворяющими схеме 8.3. Данный вариант функции (при CL = 1) в отличие от ее Предыдущего варианта, производит прроверку наличия файла или пути.

Получить полный путь с длинными именами

Вход: АН = 7160h; CL = 2; СН — содержимое результата (СН = 80 — получить имя лиска; СН = 0 — получить полный путь); DS:SI — адрес ASCIIZ-строки с именем файла или каталога, для которых необходимо получить путь в длинной форме. Допускаются оба типа имен — длинные и короткие; ES:DI — адрес строки, в которую необходимо записать полный путь. Размер буфера должен быть достаточным для размещения пути максимальной длины (функция 71a0h).
Выход: CF = 0 — успешное выполнение функции, в результате чего полный путь от корневого каталога в виде ASCIZ-строки записывается в буфер, адрес которого указан в ES:DI; CF = 1 — АХ = код ошибки.

Получить информацию о файле по описателю

Вход: АН = 71A6h; флаг cf = 1; ВХ = дескриптор файла; DS:DX — адрес структуры
BYHANDLEFILEINFORMATION.
Выход: CF = 0 — успешное выполнение функции; CF = 1 — АХ = код ошибки. Формат структуры BYHANDLEFILEINFORMATION приведен ниже.

Y_HANDLE_FILE_INFORMATION StuiC
"DwFiieAttributes dd ?
FtCreationTimedd 2 dup(?)
FtLastAccessTime dd 2 dup(?)
FtLastWriteTime dd 2 dup(?)
DwVolumeSeria 1 Number dd ?
NFileSizeHigh dd ?
NfileSizeLow dd ?
NnunberOfLinksdd ?
NFilelndexHighdd ?
NFilelndexLow dd ?
BY_HANDLE_FILE_INFORMATION ends

Поля этой структуры описаны в следующей таблице.

Поле
Описание
dwFileAttributes
Атрибуты файла. Этот элемент может быть комбинацией следующих значений: FI LE_ATTR IBUTENORMAL (00000000H) - файл доступен по чтению и записи; этот атрибут нельзя комбинировать с другими; FILE_ATTRIBUTE_READONLY (00000001Н) - файл только для чтения; FILE_ATTRIBUTE_HIDDEN (00000002H) - скрытый файл; FILE_ATTRIBUTE_SYSTEM (00000004H) - системный файл; FI LE_ATTR IBUTEDI RECTORY (00000010H) - каталог; FILE ATTRIBUTE ARCHIVE (00000020H) - архивный файл
CreationTime
Время создания файла в 64-разрядном формате
ftLastAccessTime
Время последнего доступа к файлу в 64-разрядном формате
ftLastWriteTime
Время последней записи в файл в 64-разрядном формате
dwVolumeSeri alNumber
Серийный помер тома, на котором находится файл
NFileSizeHigh
Старшее слово значения, определяющего размер файла
NFiieSizeLow
Младшее слово значения, определяющего размер файла
NNumberOfLinks
Число связей с данным файлом. В файловых системах FAT и HPFS этот элемент всегда равен 1. В файловой системе NTFS число связей может превышать 1
NFilelndexHigh
Старшее слово уникального дескриптора, связанного с файлом
NFilelndexLow
Младшее слово уникального дескриптора, связанного с файлом. Файл однозначно определяется дескриптором
и серийным номером тома

:prg07_26.asm - программа демонстрации применения функции 71A6h прерывания 21п :для получения информации о файле по описателю.
BY_HANDLE_FILE_INFORMATION struc "DwFileAttributes dd ? FtCreationTime dd 2 dup(?) FtLastAccessTime dd 2 dup(?) FtLastWriteTime dd 2 dup(?) DwVolumeSerial Number dd ? NFileSizeHigh dd ? NfileSizeLow dd ? NnumberOfLinks dd ? NFilelndexHigh dd ? NFilelndexLow dd ? BY_HANDLE_F1LE_INFORMATION ends
.data
file_info_ BY_HANDLE_FILE_INFORMATION <>
poir,t_find_ dd file_info_
filename db 'my_file with long name.txt'.O
point_fname dd filename
handle dw 0
:.........
.code

.файл, о котором будем получать информацию

mov bx.0100h+0400h;не использовать буферизацию
содержимое 01 в псевдоним
movdx.l юткрыть файл, если он существует, иначе вернуть ошибку Ids si .point_fname-.формируем указатель на имя файла
mov di.7 repeat:mov ax.716ch
xor ex.ex
int21h
jnc ml
mov dx.10h
jmp repeat ml: mov handle.ax
действия при успешном открытии файла:
добавить в конец псевдонима символ 7 ; номер функции DOS атрибуты файла - обычный файл - доступ для чтения-записи
открываем файл
.если файл существовал, то переход
;создать файл
:переход - повторим открытие файла
:сохраним дескриптор файла
.получаем информацию о файле mov bx. handle
stc ;это обязательно
Idsdx.point_find_;формируем указатель на структуру BY_HANDLE_FILE_INFORMATION

Создать псевдоним

Функция 71A8h предназначена для генерации короткого (в формате 8.3) имени для заданного файла с длинным именем.
Вход: АН = 71A8h; DS:SI — адрес строки (с нулевым символом в конце), содержащей длинное имя нужного файла без указания пути; ES:DI — адрес буфера, в котором возвращается псевдоним; DH — формат псевдонима (0—11 -символьное имя элемента каталога; 1 — имя файла в формате 8.3); DL — набор символов для длинного имени и псевдонима. Это значение — упакованная величина в формате: биты 0..3 — набор символов в prpprg0дном имени файла (0 — Windows ANSI; I — OEM; 2 — Unicode); биты 4..7 — набор символов в создаваемом коротком имени (0 — Windows ANSI; I - OEM; 2 - Unicode).
Выход: CF ¦ 0 — успешное выполнение функции; CF = 1 — АХ = код ошибки.

:prgO7_27.asm - программа демонстрации применения функции 71A8h прерывания 21h ;для создания псевдонима.
.'data'"
fi1enamejong db 'my_file with long name.txt'.0
point_fname_long dd fi1enamejong
filename_short db 11 dup (20h)
point_fname_short dd filename short
handle dw 0
:.........
.code
mov bx.0100h+0400h;He использовать буферизацию + содержимое DI в псевдоним
movdx.l :открыть файл, если он существует, иначе вернуть ошибку
Ids si,point fname_long ;формируем указатель на имя файла
movdi.7 :добавить в конец псевдонима символ 7 repeat:mov ax,716ch ;номер функции DOS
хогсх.сх атрибуты файла - обычный файл - доступ для чтения-записи
int 21h открываем файл
jnc ml :если файл существовал, то переход
movdx.lOh :создать файл
jmp repeat ;переход - повторим открытие файла ml: mov handle.ax :сохранин дескриптор файла создадим псевдоним
Ids si.point_fname_long
les di,point_fname_short
mov dh. 1:prg07_27.asm - программа демонстрации применения функции 71A8h прерывания 21h ;для создания псевдонима.
mov dl. 0
mov ax,7la8h int 21h действия при успешном открытии файла

Действие данной функции несколько отличается от процесса формирования псевдонима файла операционной системой и заключается в том, что длинное имя попросту обрезается по границам 8.3. В этом несложно убедиться, проанализировав работу приведенной выше программы в отладчике.

Поиск файлов и каталогов

В Windows-версии MS DOS процесс поиска несколько отличается от рассмотре-ного выше. Для этого используются три функции и структура WIN32_FIND_DATA в памяти, в которой возвращается информация о файле. Для запуска процесса поиска вызывается функция 714eh — найти первый файл.
Вход: АН = 714eh; CL — атрибуты искомых файлов (0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004И — системный файл; 0008И — метка тома; 00lOh — каталог; 0020h — архивный файл); СН — дополнительные атрибуты искомых файлов (0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004h — системный файл; 0008h — метка тома; 00lOh — каталог; 0020h — архивный файл); DS:DX — адрес ASCIIZ-строки с именем искомого файла или каталога. Допускаются оба типа имен — длинные и короткие. В именах допустимы символы шаблона * и ?; ES-.DI — адрес структуры WI N32_F I ND_DATA, в которой будет возвращена ин-_ формация о файле; SI — формат, в котором возвращается дата и время
(О — дата и время возвращаются в 64-разрядном формате; 1 — дата и время возвращаются в формате MS DOS).
Выход: CF = 0 — успешное выполнение функции, в результате в регистрах АХ и СХ возвращается следующая информация: АХ = дескриптор, использующийся далее для процесса поиска; СХ = возможные значения: 0000 — все символы структуры WIN32_FIND_DATA, составляющие основное и альтернативное имя файла, успешно преобразованы из Unicode; 0001 — основное имя, возвращенное в структуре WIN32_FIND_DATA, содержит знаки подчеркивания на месте символов, не преобразованных из Unicode; 0002 — альтернативное имя, возвращенное в структуре WIN32_FIND_DATA, содержит знаки подчеркивания на месте символов, не преобразованных из Unicode; CF = 1 — АХ = код ошибки при неудачном выполнении функции. Вызов функции 714eh приводит к заполнению полей структуры WIN32_FIND_ DATA, после чего можно проанализировать ее поля. Основной интерес представляют поля основного (CfileName) и альтернативного (CaHernateFiieName) имен. Их можно анализировать на предмет удовлетворения условиям поиска. Если необходимо продолжить поиск, вызывается функция 714fh — найти следующий файл. Если же поиск считается удачным либо его необходимо прекратить, то вызывается функция 71alh — прекратить поиск. Ниже приведены порядок вызова функций 714fh и 71alh и формат структуры WIN32_FIND_DATA.
Вход: АН = 714fh; ВХ = дескриптор, полученный функцией 714eh; ES:DI — адрес структуры WIN32FINDDATA, в которой будет возвращена информация о файле; SI — формат, в котором возвращается дата и время (0 — дата и время возвращаются в 64-разрядном формате; 1 — дата и время возвращаются в формате MS DOS).
Выход: CF = 0 — успешное выполнение функции, в результате в регистрах АХ и СХ возвращается следующая информация: СХ = возможные значения: 0000 — все символы структуры WIN32FINDDATA, составляющие основное и альтернативное имя файла, успешно преобразованы из Unicode; 0001 — основное имя, возвращенное в структуре WIN32FINDDATA, содержит знаки подчеркивания на месте символов, не преобразованных из Unicode; 0002 — альтернативное имя, возвращенное в структуре WIN32FINDDATA, содержит знаки подчеркивания на месте символов, не преобразованных из Unicode; CF = 1 — АХ = код ошибки при неудачном выполнении функции. Функция 714eh в отличие от аналогичных функций «старой» MS DOS использует не область DTA, а некоторый блок в памяти. Этот блок важно своевременно освобождать, для этого и предназначена функция 71alh.
Вход: АН = 71Alh; ВХ = дескриптор, полученный функцией 714eh. Выход: CF = 0 — успешное выполнение функции; CF = 1 — АХ = код ошибки при неудачном выполнении функции.

Ниже приведена структура WI N32_FIND_DATA, в которую в процессе поиска записывается информация о файлах.

WIN32_FIND_DATA struc
DwFlleAttributes dd ?
FtCreationTime dd 2 dup(?)
FtLastAccessTime dd 2 dup(?)
FtLastWriteTime dd 2 dup(?)
NFileSizeHigh dd ? .размер файла в байтах (старшее слово)
NFiieSizeLow dd ? ;размер файла в байтах (младшее слово)
DwReservedO dd 0 ;резерв
OwReservedl dd 0 ;резерв
CFileName db MAX_PATH dup(?)
CAlternateFileName db 14 dup(?) WIN32_FIND_DATA ends

Поля этой структуры описаны в следующей таблице.

dwFileAttributes
Атрибуты найденного файла (см. описание аналогичного элемента структуры BY HANDLE FILE INFORMATION)
ftCreationTime
Время создания файла в одном из двух форматов: MS DOS или в 64-разрядном, в зависимости от параметров, указанных при вызове функций 714eh (найти первый файл) и 714fh (найти следующий файл)
ftLastAccessTime
Время последнего доступа к файлу в одном из двух форматов: MS DOS или в 64-разрядном, в зависимости от параметров, указанных при вызове функций 714eh и 714fh
fUastWrUeTime
MS DOS или в 64-разрядном, в зависимости от параметров, указанных при вызове функций 714eh и 714fh
CFileName
ASCIIZ-строка, содержащая имя файла. Размер строки должен быть не менее 256 символов
cAlternateFileName
ASCIIZ-строка, содержащая альтернативное имя файла в стандартном формате 8.3. Если элемент cFileName содержит имя в формате 8.3 или файловая система не поддерживает альтернативные имена в формате 8.3, то элемент cAlternateFileName равен нулю

Приведем пример поиска файла по шаблону. Для этого предварительно создадим несколько файлов в соответствии с шаблоном file*.*. Среди этих файлов должен быть файл file_O5.txt. В отладчике проследим за тем, как изменяется
содержимое области памяти, отведенное для экземпляра структуры WIN32_FIND_ DATA. Выход из программы — при обнаружении файла file_5.txt

 

 

:prgO7_28.asm - программа демонстрации поиска файла по шаблону.

WIN32_FIND_DATA -uc
DwFlleAttributes dd ?
FtCreationTime dd 2 dup(?)
FtLastAccessTime dd 2 dup(?)
FtLastWriteTime dd 2 dup(?)
NFileSizeHigh dd ? .размер файла в байтах (старшее слово)
NFileSizeLow dd ? .размер файла в байтах (младшее слово)
DwReservedO dd 0 ;резерв
DwReservedl dd 0 :резерв
CFileName db 260 dup(?)
CAlternateFileName db 14 dup(?)
WIN32_FIND_DATA ends
.data
find_ WIN32_FIND_DATA <>
point_find_ dd find_
f_name_pattern db 'file_*.*'.O
point_f_name_pattern dd f_name_pattern
filename db 'file_05.txt',0 :искомый файл
1e*n_fi1ename=$-fi1ename
handle dw 0
movCL.O ;атрибуты искомого файла
movch.O ;дополнителные атрибуты для поиска
Ids dx,point_f_name_pattern ;формируем указатель на строку с шаблоном
les di.point_find_;формируем указатель на экземпляр структуры WIN32_FIND_DATA
movax.714eh :номер функции DOS
int 21h
jc exit
;в ах был возвращен дескриптор - если нужно, то его необходимо сохранить:

mov handle.ax
:проверяем, тот ли это файл: ml: mov ex.1en_fi1ename
lea di.find_.CfileName
lea si .filename repe empsb
jz exit ;продолжаем поиск - в Ьх дескриптор, полученный от 714eh:
mov bx.handle
les di.point_find_ :формируем указатель на экземпляр структуры WIN32_FIND_DATA
mov ax.714fh :номер функции DOS
хог si.si :формат даты
int 21h
jnc ml exit: завершить поиск
mov ax.71alh
mov bx.handle
int 21h

В отладчике хорошо видно, что выход из данной программы происходит в двух случаях:

  • когда файл найден, выход из программы производится в результате сравнения командой empsb (флаг ZF устанавливается в 1);
  • когда файлов, удовлетворяющих шаблону, нет, функция поиска 714еп и 714fh завершается неудачей (флаг CF устанавливается в 1).

В качестве шаблона можно задать символы *.*, тогда мы сможем получить имена и проанализировать все файлы в текущем каталоге. Это может понадобиться при программировании операции перемещения или копирования каталога.
Остальные функции работы с файлами, предназначенные для записи/чтения/позиционирования, остались прежними.


Книжный магазин