- •Работа с файловой системой dos
- •Получение справочной информации
- •Void far *drv_addr;
- •24.11Стандартные библиотеки трансляторов Microsoft qc 2.5 и Borland содержат несколько функций, облегчающих получение справочной информации о состоянии дисковой подсистемы.
- •Void _dos_getdrive(unsigned *drive);
- •Void _dos_setdrive(unsigned drive, unsigned *drivecount);
- •Void main(void);
- •Void main(void) {
- •Создание, удаление и переименование каталогов
- •Void main(void);
- •Void main(void) {
- •Void main(void);
- •Void main(void) {
- •If(!mkdir(test_dir)) {
- •Int rename(char *oldname, char *newname);
- •Поиск в каталогах
- •Int _dos_findfirst(char *pattern, struct find_t *found, unsigned attr);
- •Int _dos_findnext(struct find_t *found);
- •Void print_info(struct find_t *pfind) {
- •Работа с файлами
- •Int creat(char *filename, int mode);
- •Int open(char *filename,
- •Int oflag [, int pmode]);
- •Int close(int handle);
- •3.5. Чтение/запись файлов
- •Int write(int handle, void *buffer, unsigned count);
- •Int read(int handle, void *buffer, unsigned count);
- •Void main(int, char *[]);
- •Void main(int argc, char *argv[]) {
- •Int source, taget, I;
- •Int eof(int handle);
- •3.6. Позиционирование
- •Void main(void);
- •Void main(void) {
- •Int handle;
- •3.7. Изменение атрибутов, времени и даты файлов
- •Void main(int argc, char *argv[]);
- •Void main(int argc, char *argv[]) {
- •3.8. Буферизация ввода/вывода
- •Int _cnt; // количество оставшихся байтов
- •Int fclose(file *stream);
- •Int fileno(file *stream);
- •Int fseek(file *stream, long offset, int origin);
- •Int fgetpos(file *stream, fpos_t *pos);
- •Int fsetpos(file *stream, fpos_t *pos);
- •Int fputc(int c, file *stream);
- •Int fgetc(file *stream);
- •Int fputs(char *string, file *stream);
- •Int fgets(char *string, int n, file *stream);
- •Int fprintf(file *stream, char *format [,arg]...);
- •Int fscanf(file *stream, char *format [,arg]...);
- •Void setbuf(file *stream, char *buffer);
- •Int setvbuf(file *stream, char *buffer, int mode,
- •Int fflush(file *stream);
- •Void filecpy(file *stream_from, file *stream_to);
- •Void main(int argc, char *argv[]) {
- •Void filecpy(file *stream_from, file *stream_to) {
- •3.9. Другие функции для работы с файлами
- •Int setmode(int handle, int mode);
- •Void rewind(file *stream);
- •Int dup(int handle);
- •Int dup2(int handle1, int handle2);
- •3.10. Таблица открытых файлов
Получение справочной информации
Прежде чем мы начнем обзор функций получения справочной информации о состоянии и параметрах дисковой подсистемы, введем понятие текущего диска и текущего каталога.
Если запускается программа, которая находится в каком-либо каталоге на одном из дисков, то эти диск и каталог становятся текущими для 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;
