Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Работа с файловой системой DOS.doc
Скачиваний:
3
Добавлен:
16.11.2019
Размер:
299.01 Кб
Скачать

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

Прежде чем мы начнем обзор функций получения справочной информации о состоянии и параметрах дисковой подсистемы, введем понятие текущего диска и текущего каталога.

Если запускается программа, которая находится в каком-либо каталоге на одном из дисков, то эти диск и каталог становятся текущими для MS-DOS. Это можно понимать в том смысле, что программе не требуется каждый раз при работе с файлами указывать требуемый диск или каталог.

В любой момент времени программа может узнать текущие диск или каталог, а также заменить их. Для этого она должна использовать специальные функции прерывания INT 21h.

Для определения текущего диска можно использовать функцию 0Eh, которая имеет следующий формат вызова:

На входе:

AH = 0Eh

DL = Номер дисковода (0 - А:, 1 - В:, и т.д.)

На выходе:

AL = Общее количество дисководов в системе. Эта величина соответствует параметру LASTDRIVE файла CONFIG.SYS.

Пример:

mov ah, 0Eh

mov dl, 02 ; диск C:

int 21h

mov disks, al ; занесение данных в переменную disks

Для того чтобы узнать номер текущего дисковода, программа может воспользоваться функцией 19h:

На входе:

AH = 19h

На выходе:

AL = Номер текущего дисковода (0 - А:, 1 - В:, и т.д.).

Функция 3Bh предназначена для установки текущего каталога:

На входе:

AH = 3Bh

DL = Номер дисковода (0 - текущий, 1 - А:, 2 - В:, и т.д.)

DS:DX = Адрес буфера, содержащего путь каталога, который должен стать текущим.

На выходе:

AX = Код ошибки, если CF установлен в 1.

Буфер пути может иметь максимальный размер 64 байта. Он должен содержать путь в формате ASCIIZ, т.е. строку, закрытую двоичным нулем, например: "path\dirname",0. Строка не должна содержать литеры, обозначающие диск. Если текущим должен стать корневой каталог, строка должна состоять только из одного двоичного нуля.

Для того чтобы узнать текущий каталог, можно воспользоваться функцией 47h:

На входе:

AH = 47h

DL = Номер дисковода (0 - текущий, 1 - А:, 2 - В:, и т.д.)

DS:SI = Адрес буфера для записи пути текущего каталога.

На выходе:

AX = Код ошибки, если флаг переноса CF установлен в 1.

Буфер должен иметь размер не менее 64 байтов, текущий каталог возвращается в формате ASCIIZ без литеры, обозначающей диск. Если текущим является корневой каталог, регистровая пара DS:SI будет указывать на нулевую строку (состоящую из одного двоичного нуля).

Функции MS-DOS могут помочь в получении информации, необходимой для организации доступа к диску на уровне секторов и кластеров. При этом вы будете избавлены от необходимости читать в память и анализированть содержимое загрузочного сектора логического диска.

Информация о таблице размещения файлов FAT для текущего диска может быть получена с помощью функции 1Bh прерывания INT 21h, имеющего следующий формат:

На входе:

AH = 1Bh

На выходе:

DS:BX = Адрес первого байта FAT. Это байт ID идентификации среды носителя данных, соответствует байту media в блоке параметров BIOS.

DX = Общее количество кластеров на диске.

AL = Количество секторов в одном кластере.

CX = Количество байтов в одном секторе.

Дополнительно эта функция возвращает информацию об общем количестве кластеров на диске, размере кластера в секторах и размере сектора в байтах.

Для получения аналогичной информации не о текущем, а о любом диске, используйте функцию 1Ch. Эта функция полностью аналогична предыдущей, за исключением того, что в регистре DL должен быть указан код дисковода: 0 - текущий, 1 - А:, 2 - В: и т.д.

Размер свободного места на диске можно узнать с помощью функции 36h, имеющей следующий формат:

На входе:

AH = 36h

DL = Номер дисковода (0 - текущий, 1 - А:, 2 - В:, и т.д.)

На выходе:

AX = Количество секторов в кластере; 0FFFFh, если был задан неправильный номер дисковода;

BX = Количество свободных кластеров на диске.

CX = Количество байтов в одном секторе.

DX = Общее количество кластеров на диске.

Эта функция возвращает в регистре AX число 0FFFFh, если неправильно указан номер дисковода.

Формат блока управления устройствами (DDCB) для DOS версии 4.х и выше:

(0)

1

drv_num

номер устройства (0 соответствует устройству А:, 1 - В: и т.д.)

(+1)

1

drv_numd

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

(+2)

2

sec_size

размер сектора в байтах

(+4)

1

clu_size

число, на единицу меньшее количества секторов в кластере

(+5)

1

clu_base

если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size

(+6)

2

boot_siz

количество зарезервированных секторов (boot-сектора, начало корневого каталога)

(+8)

1

fat_num

количество копий FAT

(+9)

2

max_dir

максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве)

(+11)

2

data_sec

номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2)

(+13)

2

hi_clust

максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных)

(+15)

1

fat_size

количество секторов, занимаемых одной копией FAT

(+16)

1

reserv1

зарезервироано

(+17)

2

root_sec

номер первого сектора корневого каталога

(+19)

4

drv_addr

FAR-адрес заголовка драйвера, обслуживающего данное устройство

(+23)

1

media

байт описания среды носителя данных

(+24)

1

acc_flag

флаг доступа, 0 означает, что к устройству был доступ

(+25)

4

next

адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF

(+29)

2

reserv2

зарезервироано

(+31)

2

built

число FFFF в этом поле означает, что блок DDCB был построен

Определение типа DDCB:

/* Блок управления устройством DOS */

#pragma pack(1)

typedef struct _DDCB_ {

unsigned char drv_num;

unsigned char drv_numd;

unsigned sec_size;

unsigned char clu_size;

unsigned char clu_base;

unsigned boot_siz;

unsigned char fat_num;

unsigned max_dir;

unsigned data_sec;

unsigned hi_clust;

unsigned char fat_size;

char reserv1;

unsigned root_sec;