MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 19, М.: Диалог-МИФИ, 1995, 253 стр. 3.1. Получение справочной информацииВ этом разделе мы опишем наиболее нужные, на наш взгляд, функции MS-DOS, предназначенные для получения справочной информации о состоянии дисковой системы. Текущий диск и текущий каталогВ любой момент времени программа может определить текущий диск или текущий каталог, а также сменить текущий диск или текущий каталог. Для этого она должна использовать специальные функции прерывания INT 21h . Для того чтобы узнать номер текущего диска,
программа может воспользоваться функцией 19h:
Для установки текущего диска можно
использовать функцию 0Eh, которая имеет следующие
параметры вызова:
Для того чтобы узнать текущий каталог, вы
можете воспользоваться функцией 47h:
Буфер должен иметь размер не менее 64 байт. Функция 47h возвращает текущий каталог в формате ASCIIZ (то есть строку, закрытую двоичным нулем, например: "path\dirname",0) без символа, обозначающего диск. Если текущим является корневой каталог, регистровая пара DS:SI будет указывать на нулевую строку (состоящую из одного двоичного нуля). Функция 3Bh предназначена для установки
текущего каталога:
Буфер может иметь максимальный размер 64 байт. Он должен содержать путь в формате ASCIIZ. Строка не должна содержать символ, обозначающий диск. Если текущим должен стать корневой каталог, строка должна состоять только из одного двоичного нуля. Определение размера кластера и сектораФункции MS-DOS могут помочь вам в получении информации, необходимой для организации доступа к диску на уровне секторов и кластеров. При этом вы будете избавлены от необходимости читать в память и анализировать содержимое загрузочного сектора логического диска. Информация о таблице размещения файлов FAT для
текущего диска может быть получена с помощью
функции 1Bh прерывания INT 21h , имеющего следующие
параметры вызова:
Дополнительно эта функция возвращает общее количество кластеров на диске, размер кластера в секторах и размер сектора в байтах. Для старых версий MS-DOS регистровая пара DS:BX указывала на FAT , считанный в память. Более поздние версии операционной системы могут содержать по этому адресу только часть таблицы размещения файлов . Для получения аналогичной информации не о текущем, а о любом диске, используйте функцию 1Ch. Эта функция полностью аналогична предыдущей, за исключением того, что в регистре DL должен быть указан номер НГМД или НМД: 0 - текущий, 1 - А:, 2 - В: и т. д. Определение размера свободного пространстваЕсли вас интересует размер свободного места на
диске, вы можете его узнать с помощью функции 36h:
Эта функция возвращает в регистре AX число 0FFFFh, если вы неправильно указали номер устройства. Блок управления устройством DDCBПри обсуждении векторной таблицы связи в предыдущем томе "Библиотеки системного программиста" мы рассказывали о блоках управления устройствами DDCB . Поле dev_cb векторной таблицы связи содержит дальний адрес цепочки этих блоков. Для получения адреса блока DDCB можно
воспользоваться недокументированной функцией
32h:
Для получения адреса блока DDCB текущего диска можно также воспользоваться недокументированной функцией 1Fh, которая имеет формат, аналогичный функции 32h, за исключением того, что для нее не надо задавать номер устройства в регистре DL. Флаг прерыванияС помощью функции 33h программа может проверить
или установить флаг прерывания при помощи
комбинации клавиш <Ctrl+Break> и, кроме того, узнать
номер диска, с которого выполнялась загрузка
операционной системы:
Сведения о диске, который был использован для загрузки операционной системы, могут понадобиться вам, например, для поиска файла командного интерпретатора. Состояние флага прерывания при помощи комбинации клавиш <Ctrl+Break> влияет на возможность прервать выполнение программы. Если прерывание запрещено, MS-DOS проверяет эту комбинацию клавиш только при вызове функций стандартного ввода/вывода на консоль, принтер и последовательный порт. Если же прерывание разрешено, указанная комбинация клавиш проверяется и при вызове других функций MS-DOS. Если пользователь нажал комбинацию клавиш <Ctrl+Break>, операционная система выполняет прерывание INT 23h , которое завершает работу текущей программы. Адрес области DTAФункция 2Fh возвращает в регистровой паре ES:BX адрес текущей области DTA (Disk Transfer Area ), которая используется при поиске файлов в каталогах. Этот адрес необходим резидентным программам, о чем мы говорили в предыдущем томе "Библиотеки системного программиста". Флаг проверки записиФункция 54h позволяет программе узнать текущее состояние флага проверки записи информации на диск. В регистре AL эта функция возвращает текущее состояние флага. Если содержимое регистра равно 1, после записи сектора операционная система считывает его для проверки. Разумеется, такая проверка снижает скорость работы программы. Если после вызова функции регистр AL содержит 0, проверка записи не выполняется. Для установки флага проверки записи можно использовать функцию 2Eh. Перед вызовом функции в регистр AL необходимо занести новое значение флага проверки: 0 - проверка не нужна; 1 - должна выполняться проверка записанной информации. Функции библиотеки Borland C++Стандартная библиотека Borland C++ содержит несколько функций, облегчающих получение справочной информации о состоянии дисковой системы. _dos_getdiskfreeФункция _dos_getdiskfree использует функцию 36h для получения информации о диске. Файл dos.h содержит такое описание этой функции: unsigned _dos_getdiskfree (unsigned drive, struct diskfree_t *diskspace); Параметр drive задает номер используемого устройства: 0 - текущий, 1 - А:, и т. д. Информация возвращается в структуре diskfree_t, которая определена также в файле dos.h: struct diskfree_t { unsigned total_clusters; unsigned avail_clusters; unsigned sectors_per_cluster; unsigned bytes_per_sector; }; Поля этой структуры описаны ниже:
_dos_getdrive и _dos_setdriveДля получения номера текущего диска и для установки номера текущего диска можно использовать, соответственно, функции _dos_getdrive и _dos_setdrive . Функция _dos_getdrive имеет следующий прототип: void _dos_getdrive (unsigned *drive); Она пользуется функцией 19h для получения номера текущего диска, который записывается по адресу, задаваемому параметром drive. Значение 1 соответствует диску А:, 2 - В:, и т. д. Функция _dos_setdrive предназначена для установки текущего диска и может быть использована для определения общего числа дисков в системе: void _dos_setdrive (unsigned drive, unsigned *drivecount); Параметр drive определяет текущий диск (1 - А:, и т. д.). В переменную, адрес которой передается через второй параметр, функция записывает общее количество логических дисков, установленных в системе. Функция _dos_setdrive использует функцию 0Eh прерывания INT 21h . Программа DISKINF2Для иллюстрации способов использования функций _dos_getdrive , _dos_setdrive и _dos_getdiskfree мы составили программу DISKINF2 (листинг 3.1). Листинг 3.1. Файл diskinf2\diskinf2.cpp #include <dos.h> #include <bios.h> #include <conio.h> #include <stdio.h> void main(void) { struct diskfree_t dinfo; unsigned drive, drivecount; printf("\n" "\nОпределение параметров текущего логического диска" "\n (C)Фролов А., 1995\n"); // Определяем номер текущего диска _dos_getdrive (&drive); // Выводим на экран обозначение текущего диска printf("\nТекущий диск: %c:\n", 'A' + drive - 1); // Вызываем функцию установки текущего диска. // Мы не изменяем текущий диск, вызов этой функции // нужен нам для определения количества установленных // в системе логических дисков _dos_setdrive (drive, &drivecount); // Получаем характеристики текущего диска _dos_getdiskfree (drive, &dinfo); printf("\nОбщее количество кластеров на диске: %u" "\nКоличество свободных кластеров: %u" "\nКоличество секторов в кластере: %u" "\nКоличество байт в секторе: %u" "\nРазмер свободного пространства в байтах: %ld" "\n", dinfo.total_clusters, dinfo.avail_clusters, dinfo.sectors_per_cluster, dinfo.bytes_per_sector, (long)dinfo.avail_clusters * dinfo.sectors_per_cluster * dinfo.bytes_per_sector ); printf("\nКоличество логических дисков: %d" "\n", drivecount); } |