Dos fn 32h дать информацию dos о диске


Dos fn 32h: дать информацию dos о диске

Чаще всего с контроллером BETA используется 5.25 дисковод двойной плотности. Дисководы высокой плотности (1.2, 1.44MB) использовать не имеет смысла, т.к. данный режим не поддерживается. Если у Вас применяется 40-дорожечный дисковод, у Вас будут проблемы с перезаписью, при обмене программами, т.к. 80-дорожечные диски на таком дисководе не читаются, а 40-дорожечные на 80-дорожечном — читаются, но не пишутся. Напомню, что режим «40» на 80-дорожечном дисководе не обеспечивает стандартную 40-дорожечную запись (см. фирменную инструкцию)!

Дисковод с двойной плотностью называют 80-дорожечным, хотя практически он обеспечивает доступ к 84. 86 дорожкам (в зависимости от конкретного дисковода и дискеты). В нумерации дорожек имеется некоторая путаница, так как иногда используются номера цилиндров (пар дорожек, 0.85) и номер стороны (0,1; 0-верхняя), а иногда — сквозная нумерация (0.171; четные номера — верхние). При использовании TR-DOS встречаются оба варианта. Доступ к дорожкам 80.85 возможен при вызове процедур из ПЗУ; стандартными командами DOS он не поддерживается.

TR-DOS дает 16 секторов на дорожке и 256 байтов в секторе. Уменьшенный (в MS-DOS, например, сектор=512) размер сектора имеет преимущество при хранении большого числа коротких файлов, т.к. более экономно расходуется дисковое пространство (если файл имеет, к примеру, длину всего 1 байт, на диске он все равно займет целый сектор). Кроме того, при использовании файлов произвольного доступа увеличивается скорость операций.

Сказанное дает возможность подсчитать количество секторов и вместимость форматированного диска (учитывая, что TR-DOS использует внешнюю [0] дорожку для хранения системной информации о диске):

40 дорожек односторонний = 38*16 = 624 сектора *256=156 KB 40 дорожек двухсторонний = 79*16 = 1264 сектора *256=316 KB 80 дорожек односторонний = 79*16 = 1264 сектора *256=316 KB 80 дорожек двухсторонний = 159*16 = 2544 сектора *256=636 KB 86 дорожек (максим. кол.) = 171*16 = 2736 сектора *256=684 KB

Это означает, что на 1 дорожке помещается 4 KB, или 4 сектора на 1 KB. Таким образом, разделив количество свободных секторов на 4, можно узнать, сколько килобайт свободного пространства осталось на диске (напомню, 1KB=1024 байт).

TR-DOS использует двойную плотность записи, поэтому получаем 80 дорожек и 16 секторов по 256 байт на дорожке.

СТРУКТУРА ДИСКЕТЫ TR-DOS

Вся служебная информация о дискете размещается на нулевой дорожке. Первые восемь секторов (№ 0. 7) содержат каталог файлов, следующий сектор — № 8 — системный, в нем записаны ее параметры. С дорожки номер 1 начинается основное пространство дискеты, где собственно и хранятся файлы. Как видите, организация диска очень проста, по сравнению с MS-DOS, поэтому и возникают сложности с удалением файлов, требуется уплотнение дискового пространства командой MOVE.

Сектора нулевой дорожки с номерами от 9 по 15 обычно не используются и при помощи рассмотренных ниже процедур DOS в них можно разместить какую-либо собственную информацию. Существует, например, оригинальный «boot», занимающий в основной области диска всего один сектор, который при записи размещает свои коды в свободных секторах нулевой дорожки (автор Ю. Власов). Однако, пользуясь этими секторами, не записывайте на такой диск при помощи «Magic» — данная процедура испортит сектора с номерами 10, 11 о «Magic» см. далее).

Процедура удаления файла заключается в замене первого байта его имени кодом 01, после чего, файл считается удаленным и не отображается в каталоге. Вся информация на дискете сохраняется, пока не будет выполнена команда MOVE. Если удален файл в конце каталога, первый байт имени может получить нулевое значение (признак свободного пространства).

Для файлов типа «DATA», поле длины (Length) также представляет собой длину массива (переменной), а поле адреса (Start)-начальный адрес этого массива в момент записи, с учетом 257-байтного сдвига на величину буфера обмена (см. далее). Для дисковых файлов (#), поле длины содержит длину заполненной части блока, от 0 до 4096 (напомню, что эти файлы записываются блоками по 4096 байт, т.е. 16 секторов, под одинаковым именем). Старший байт поля адреса для дискового файла равен 32, а младший — номеру блока в файле (0, 1, 2,.), что в каталоге отображается как 8192, 8193, 8194.

На дискете заголовки файлов записаны в первых 8 секторах (с номерами от 0 до 7) нулевой дорожки. Кроме того, следует заметить, что порядковый номер заголовка файла в каталоге имеет следующее свойство: старшая половита байта соответствует номеру сектора, в котором записан заголовок, а младшая — номеру заголовка в секторе. Это бывает полезно при работе с диском.

Как видим, номер строки автостарта BASIC- программы не входит в данные заголовка. Он записывается вместе с программой, 5 байт после конца программы или области переменных, если они есть — в поле ELINE: после разделителя полей #80 следует байт #AA и 2 байта номера строки (младший, старший). В отличие от кассеты, автостарт с нулевой строки не выполняется.

Поле «число секторов» используется при копировании файла, а поле «длина файла» — при его загрузке. Обнулив число секторов, можно сделать файл некопируемым (хотя эта защита так же легко и снимается).

Каталог дискеты вмещает максимум 128 файлов, считая и стертые; а так как подкаталоги в TR-DOS не создаются, то при большом числе коротких файлов каталог переполняется, и часть пространства на дискете остается неиспользованной.

СТРУКТУРА СИСТЕМНОГО СЕКТОРА

Системную информацию о дискете содержит 8-й сектор нулевой дорожки, точнее, конец этого сектора, начиная с 225-го байта:

MS-DOS. Форматирование дисков. Установка и вывод метки диска

Для использования магнитных дисков необходимо предварительно инициализировать, такая разметка называется форматированием. При форматировании диска на его магнитной поверхности создаются концентрические окружности(дорожки). Каждая дорожка разбивается на секторы. Каждый сектор маркируется магнитным маркером. Группа смежных секторов называется кластером. Размер каждого сектора независимо от местоположения дорожки занимает 512 байт. Межсекторное пространство образуется для того, чтобы процессор успевал обрабатывать ин-фу, которая считывается с диска.

Команда форматирования диска

Команды format применяются для того, чтобы подготовить к работе новый диск, подготовить к работе системный диск, отчистить диск от ин-фы и отметить дефективные участки. Опции:

[/S]-формат диска с переносом системных файлов

[/V]-задание метки диска

[/B]-создание системной дискеты без переноса системных файлов с помощью — SYS

[/1]-форматирование только 1-ой стороны диска(по умолчанию 2-е)

[/8]-разбиение на 8 секторов(по умолчанию 9)

[/4]-форматирование с высокой степенью плотностью.

Q-при быстром форматировании отчищается только таблица размещения файлов, при этом возможно восстановление файлов.

U-при полном форматировании заново нарезаются дорожки, разбиваются на сектора, предыдущая ин-фа восстановлению не подлежит.

2)F format Команда f format работает в диалоговом режиме запрос подтверждения для каждой опции.

3)F disk – разбиение HDD на логические диски, работает в диалоговом режиме. После разбиения, каждый логический диск форматируется отдельно.

4)Label – устанавливает метку тома.

5)Vol – выдаёт метку тома.

Атрибуты файлов.

Для каждого файла соответствующая ему запись в каталоге(элемент каталога), содержит атрибуты файла. В DOS-е может обрабатываться 4-е атрибута:

”только для чтения (read-only)”, — R

”скрытые (hidden)”, — H

”системный (system)”, — S

Утилиты MS-DOS(ver,sys,attrib,diskcomp,diskcopy,chkdsk).

Ver- вывод сведений о версии windows

Sys- создание системной дискеты(внешняя утилита)

Attrib- отображение и изменение атрибутов файлов

Diskcomp- сравнение содержимого 2-х гибких дисков

Diskcopy- копирование содержимого одного гибкого диска на другой

Chkdsk- проверка диска и вывод статистики

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: На стипендию можно купить что-нибудь, но не больше. 8987 — | 7235 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

Dos fn 32h: дать информацию dos о диске

Итак, вам нужно переустановить систему (к примеру, Windows 2000) на компьютере, подключенном к сети вашего предприятия. Причем переустановить начисто, с переформатированием винчестера. CD-ROM’а на этой машине нет — зачем ставить их на все машины, раз есть сеть? Есть только дисковод для дискет. Ваши действия? Сколько времени вам понадобится? А если не пользоваться отверткой?

Самый быстрый и эффективный способ решения этой задачи — установить систему с сетевого сервера, загрузившись с обычной дискеты. Не нужно привинчивать к машине второй винчестер или CD-ROM (а если она под гарантийной пломбой?), не нужно заботиться о сохранении существующих логических дисков. Нужна всего лишь одна дискета. К примеру, на дискете, которой пользуется автор статьи, успешно помещается (частично — в сжатом виде) следующее:

операционная система с поддержкой файловой системы FAT32 и русского языка;
четыре различных драйвера сетевых плат (3Com, Intel, Realtek, SYS) с автоматическим определением установленной платы и загрузкой нужного драйвера;
сетевой клиент, работающий по протоколу TCP/IP с автоматическим получением IP-адреса от DHCP-сервера;
универсальные (работающие с любыми моделями устройств) драйверы CD-ROM и мыши;
Volkov Commander;
утилиты для разбиения и форматирования винчестера;
конфигурационные файлы для полностью автоматической установки Windows 2000 и Office 2000.
С помощью такой дискеты можно выполнять практически любые работы по техническому обслуживанию и диагностике неисправностей сетевых станций. А если подключить сетевой диск, то с него можно запустить и любые другие программы, в том числе, разумеется, и установку Windows.

Что же нужно, чтобы, загрузившись с дискеты, «увидеть» сеть? Мы рассмотрим самое простое решение, основанное на использовании сетевого протокола NetBEUI. В этом случае все необходимые файлы наверняка уместятся на дискете стандартной емкости. Если ваша цель — просто получить доступ к сети любым возможным способом, то лучше ограничиться именно такой конфигурацией. Настройка TCP/IP под DOS требует значительно больших усилий, так что во многих случаях будет проще и быстрее установить NetBEUI на том сервере, к которому нужен доступ. В любом случае, рекомендуется начать с простого варианта.

Итак, приступим. Первый необходимый компонент — это, конечно же, системная дискета с MS-DOS. Если у вас ее нет, немедленно обзаведитесь. Сходите с чистой дискетой на компьютер с Windows 95OSR2 или 98SE и запустите там сеанс MS-DOS. Убедитесь, что перед вами DOS версии не ниже 7.1 (командой ver), и сделайте дискету системной (командой sys a: или format a: /s). Поддержка сети будет работать и под более ранним версиями DOS, но они не поддерживают FAT32, и поэтому не рекомендуются к использованию.

На той же дискете унесите с собой himem.sys, а также системные утилиты: fdisk.exe, format.com, smartdrv.exe. Они будут нужны вам, если вы действительно намерены использовать эту дискету для установки Windows. Кроме того, не помешают и файлы поддержки кириллицы: keyb.com, mode.com, country.sys, display.sys, keybrd3.sys, ega3.cpi (если вы для создания системной дискеты воспользовались русской версией Windows).

Второй необходимый компонент — драйвер сетевой платы. Возьмите его с дискет, прилагавшихся к вашей плате. Драйверы для MS-DOS там есть всегда, но на них редко обращают внимание. Если дискеты не сохранились — ищите в интернете. Основной файл драйвера имеет имя вида netcardname.dos. Прочие файлы, входящие в состав драйвера, не являются необходимыми для работы, но могут оказаться полезными в процессе установки.

И наконец, самый главный компонент — MS-DOS Network Client 3.0. Где его взять? Если под рукой есть дистрибутив Windows NT Server 3.51/4.0 — то из него. Если NT Server уже установлен в вашей сети — посмотрите на нем в стандартной сетевой папке CLIENTS. Не нашли? Тогда возьмите здесь: ftp://ftp.microsoft.com/bussys/clients/msclient.

Внимание! Переходим к самому сложному этапу! Сначала необходимо аккуратно установить MS-DOS Network Client на любой работающий компьютер. Аккуратно — значит, перед установкой сделать резервные копии файлов config.sys и autoexec.bat с диска C:, после установки переписать измененные копии этих файлов на вашу дискету, а затем из резервной копии восстановить эти файлы на винчестере к первоначальному виду. Ошибки, допущенные в процессе установки, могут быть устранены позднее путем редактирования конфигурационных файлов (прежде всего protocol.ini).

Затем из папки C:\NET (именно сюда по умолчанию устанавливается сетевой клиент) перепишите на вашу дискету необходимые драйверы сетевых протоколов, а в конфигурационных файлах на дискете исправьте все пути соответствующим образом.

Пример конечного результата (конфигурация — 3Com EtherLink 905 и NetBEUI) приведен на врезке.

Dos fn 32h: дать информацию dos о диске

Теперь, после того, как мы познакомились с логической структурой диска в MS-DOS, можно приступить к изучению одной из самых развитых подсистем операционной системы — файловой системы.

Сервис файловой системы доступен программе через прерывание MS-DOS INT 21h . Многочисленные функции этого прерывания, относящиеся к файловой системе, можно разбить на группы:

  • получение справочной информации;
  • работа с каталогами;
  • работа с файлами.

Функции первой группы позволяют программе получить разностороннюю информацию, касающуюся текущего состояния дисковой подсистемы — текущие используемые диск и каталог, размер свободного места на диске, параметры логического диска и т.д.

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

Третья группа функций позволяет программе выполнять практически любые операции над файлами — создание, удаление, чтение/запись, переименование, копирование, пересылка и т.п.

Заметим, что существует два класса функций для работы с файлами. Первый класс использует управляющие блоки файлов FCB . Эти функции исплоьзовались в MS-DOS версий 1.х и имеют в настоящее время чисто исторический интерес. Вам они скорее всего никогда не будут нужны, за исключением одного случая — если вам надо составить программу, способную работать под управлением MS-DOS версии 1.0 или 1.1. В этой книге мы не будем упоминать функции, предназначенные для работы с файлами через FCB . При необходимости вы сможете найти информацию об этих функциях в руководстве по операционной системе MS-DOS.

Второй класс использует файловые индексы (handle). Этот класс функций впервые появился в MS-DOS версии 2.0. Эти функции аналогичны используемым в операционной системе UNIX.

Смысл файлового индекса очень прост. Для того чтобы начать работу с файлом, программа должна вызывать определенную функцию DOS, «открывающую» этот файл. Процесс открытия файла заключается в присвоении этому файлу определенного числа (индекса) и выполнении некоторых других инициализирующих действий. Для выполнения каких-либо операций с файлом программа, вызывая соответствующую функцию MS-DOS, должна указать индекс этого файла.

Первые пять файловых индексов зарезервированы операционной системой:

Стандартное устройство ввода (клавиатура)
1 Стандартное устройство вывода (экран)
2 Стандартное устройство для вывода сообщений об ошибках (экран)
3 Стандартное устройство последовательного ввода/вывода, обычно это асинхронный адаптер COM1 .
4 Стандартное печатающее устройство (обычно первый принтерный порт LPT1 )

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

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

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

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

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

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

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

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

На входе: AH = 0Eh
DL = Номер дисковода (0 — А:, 1 — В:, и т.д.)
На выходе: AL = Общее количество дисководов в системе. Эта величина соответствует параметру LASTDRIVE файла CONFIG.SYS.

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

На входе: AH = 19h
На выходе: AL = Номер текущего дисковода (0 — А:, 1 — В:, и т.д.).

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

На входе: AH = 3Bh
DL = Номер дисковода (0 — текущий, 1 — А:, 2 — В:, и т.д.)
DS:DX = Адрес буфера, содержащего путь каталога, который должен стать текущим.
На выходе: AX = Код ошибки, если CY установлен в 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 = Количество байтов в одном секторе.

Дополнительно эта функция возвращает информацию об общем количестве кластеров на диске, размере кластера в секторах и размере сектора в байтах. Для версий MS-DOS, более ранних, чем 2.0, регистровая пара DS:BX указывала на FAT , считанный в память. Более поздние версии операционной системы могут содержать по этому адресу только часть таблицы размещения файлов.

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


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

На входе: AH = 36h
DL = Номер дисковода ( 0 — текущий, 1 — А:, 2 — В: , и т.д.)
На выходе: AX = Количество секторов в кластере; 0FFFFh , если был задан неправильный номер дисковода;
BX = Количество свободных кластеров на диске.
CX = Количество байтов в одном секторе.
DX = Общее количество кластеров на диске.

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

При обсуждении векторной таблицы связи мы рассказывали о блоках управления устройствами DDCB . Поле dev_cb векторной таблицы связи содержит FAR -адрес цепочки этих блоков.

Приведем еще раз формат блока DDCB . Напомним, что он изменяется в зависимости от версии DOS. Для версий 2.х и 3.х блок DDCB имеет следующий формат:

(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) 2 root_sec номер первого сектора корневого каталога
(+18) 4 drv_addr FAR -адрес заголовка драйвера, обслуживающего данное устройство
(+22) 1 media байт описания среды носителя данных
(+23) 1 acc_flag флаг доступа, 0 означает, что к устройству был доступ
(+24) 4 next адрес следующего блока DDCB , для последнего блока в поле смещения находится число FFFF
————— только для DOS 2.x —————
(+28) 2 dir_clu номер начального кластера текущего каталога (0 для корневого каталога)
(+30) 64 dir_path строка в формате ASCIIZ, содержащая путь к текущему каталогу
————— DOS 3.х —————————-
(+28) 2 reserv1 зарезервировано, обычно равно 0
(+30) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Формат блока 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 был построен

Файл sysp.h содержит определение типа DDCB для MS-DOS версии 4.х:

При описании векторной таблицы связи мы приводили примеры использования блоков DDCB . Для получения адреса блока DDCB конкретного дисковода можно воспользоваться недокументированной функцией 32h . Она имеет следующий формат вызова:

На входе: AH = 32h
DL = Номер дисковода ( 0 — текущий, 1 — А:, 2 — В: , и т.д.)
На выходе: AL = 0, если был задан правильный номер дисковода;
0FFh , если был задан неправильный номер дисковода;
DS:BX = Адрес блока DDCB

Для получения адреса блока DDCB текущего диска можно воспользоваться недокументированной функцией 1Fh , которая имеет формат, аналогичный функции 32h , за исключением того, что не надо задавать номер дисковода в регистре DL .

Какая еще полезная информация может быть получена при использовании функций MS-DOS?

С помощью функции 33h программа может проверить или установить флаг Ctrl-Break и узнать номер диска, с которого выполнялась загрузка операционной системы:

На входе: AH = 33h
AL = Код подфункции:
0 — Проверить текущее состояние флага Ctrl-Break;
1 — Установить флаг Ctrl-Break;
5 — Определить номер диска, который был использован для загрузки операционной системы.
DL = Значение устанавливаемого флага Ctrl-Break для подфункции 1 (0 — OFF, 1 — ON).
На выходе: DL = Текущее состояние флага Ctrl-Break для подфункции 0;
Номер диска, использованного для загрузки операционной системы для подфункции 5 ( 1 — А:, 2 — В: , и т.д.).

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

Состояние флага Ctrl-Break влияет на возможность прервать выполнение программы нажатием комбинации клавиш Ctrl-Break или Ctrl-C. Если флаг находится в состоянии OFF, DOS проверяет эту комбинацию клавиш только при вызове функций стандартного ввода/вывода на консоль, принтер и последовательный порт. Если флаг установлен в состояние ON, комбинация клавиш проверяется и при вызове других функций MS-DOS. Если операционная система зафиксировала нажатие указанной комбинации клавиш, она выполняет прерывание INT 23h , которое завершает работу текущей программы.

Функция 2Fh возвращает в регистровой паре ES:BX адрес текущей области DTA (Disk Transfer Area), которая используется при поиске файлов в каталогах.

Функция 54h позволяет программе узнать текущее состояние флага проверки записывающейся на диск информации. В регистре AL эта функция возвращает текущее состояние флага. Если содержимое регистра равно 1, операционная система после записи сектора считывает его для проверки. Разумеется, такая проверка снижает скорость работы программы. Если после вызова функции регистр AL содержит 0, проверка записи не выполняется.

Для установки флага проверки записи можно использовать функцию 2Eh . Перед вызовом функции в регистр AL необходимо занести новое значение флага проверки: 0 — проверка не нужна; 1 — должна выполняться проверка записанной информации.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат несколько функций, облегчающих получение справочной информации о состоянии дисковой подсистемы.

Функция _dos_getdiskfree() использует функцию 36h для получения информации о диске. Файл dos.h содержит описание этой функции:

Параметр drive задает номер используемого дисковода: 0 — текущий, 1 — А: , и т.д.

Информация возвращается в структуре diskfree_t , которая определена в файле dos.h:

В этой структуре:

unsigned total_clusters общее количество кластеров на диске;
unsigned avail_clusters количество свободных кластеров;
unsigned sectors_per_cluster количество секторов, занимаемых кластером;
unsigned bytes_per_sector размер сектора в байтах.

Для получения номера текущего диска и для установки номера текущего диска можно использовать, соответственно, функции _dos_getdrive() и _dos_setdrive().

Функция _dos_getdrive() имеет формат:

Эта функция пользуется функцией 19h для получения номера текущего диска, который записывается по адресу, задаваемому параметром. Значение 1 соответствует диску А:, 2 — В:, и т.д.

Функция _dos_setdrive() предназначена для установки текущего диска и может быть использована для определения общего числа дисков в системе:

Параметр drive опеределяет текущий диск ( 1 — А: , и_т.д.), по адресу, задаваемому вторым параметром, функция записывает общее количество логических дисков, установленных в системе. Функция _dos_setdrive() использует функцию 0Eh прерывания INT 21h.

Для иллюстрации способов использования функций _dos_getdrive(), _dos_setdrive(), _dos_getdiskfree() мы составили следующую программу:

После форматирования логический диск содержит корневой каталог. Если диск форматируется как системный, в этом каталоге могут находится дескрипторы файлов операционной системы IO.SYS, MSDOS.SYS, COMMAND.COM.

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

Для создания каталога используйте функцию 39h прерывания INT 21h:

На входе: AH = 39h
DS:DX = Адрес строки в формате ASCIIZ, содержащей имя создаваемого каталога.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

Строка, имени создаваемого каталога может содержать полный путь, состоящий из имени диска и имени каталога, в котором должен быть создан каталог, или она может состоять только из одного имени каталога. В последнем случае каталог создается в текущем каталоге на текущем диске.

Размер строки с именем каталога не должен превышать по длине 64 байта.

Удалить существующий каталог можно с помощью функции 3Ah . Формат вызова этой функции аналогичен предыдущему:

На входе: AH = 3Ah
DS:DX =Адрес строки в формате ASCIIZ, содержащей имя удаляемого каталога.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

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

Для изменения имени каталогов и файлов предназначена функция 56h :

На входе: AH = 56h
DS:DX = Адрес строки в формате ASCIIZ, содержащей старое имя каталога или файла.
ES:DI = Адрес строки в формате ASCIIZ, содержащей новое имя каталога или файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

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

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

Мы уже рассказывали о функции 3Bh , с помощью которой можно изменить текущий каталог, если это необходимо.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат несколько функций, предназначенных для работы с каталогами.

Функция getcwd() предназначена для определения текущего каталога. Прототип этой функции описан в файле direct.h:

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

Если в качестве первого параметра указать NULL , функция динамически закажет буфер длиной n байтов из области кучи. Эту память впоследствии необходимо будет освободить при помощи функции free() . Функция getcwd() возвращает указатель на буфер, содержащий текущий каталог.

Приведем пример простой программы, которая выводит на экран информацию о текущем каталоге:

Для создания и удаления каталогов, изменения текущего каталога имеются функции mkdir(), rmdir(), chdir().

Все эти функции имеют один параметр — путь каталога, который имеет тип (char_*). В случае успешного выполнения операции функции возвращают 0 , при ошибке — 1 .

Приведем небольшой пример, использующий перечисленные выше функциии:

Для переименования каталогов (и файлов) предназначена функция rename():

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

Функция может возвращать один из кодов ошибки:

ENOENT Нет такого файла или каталога
EACCES Нет прав доступа
EXDEV Другой диск

Код ошибки EXDEV возвращается в том случае, когда программа указывает разные диски для старого и нового имен файлов или каталогов.

Важное замечание: если вы задаете полный путь, в строке пути повторяйте символ ‘\’ два раза. Это нужно для того, чтобы избежать конфликта с форматом представления констант в языке С. Например:

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

Пара функций 4Eh и 4Fh предназначены для сканирования каталогов.

Эти функции используются вместе следующим образом:

  • Вызывается функция 4Eh для поиска в каталоге файла, соответствующего образцу. В образце можно использовать символы ? и *, которые означают, соответственно, один любой символ и любое количество любых символов. Информация о найденном файле располагается в специальной области, назначенной каждой работающей программе — области DTA .
  • Вызывается в цикле функция 4Fh для поиска остальных файлов, удовлетворяющих образцу, заданному при вызове функции 4Eh . Условие завершения цикла — отсутствие в каталоге указанных файлов.

Приведем формат вызова функций 4Eh и 4Fh .

На входе: AH = 4Eh
CX = Атрибуты файла, которые будут использованы при поиске. Будут найдены файлы, имеющие заданный в этом регистре атрибут.
DS:DX = Адрес строки в формате ASCIIZ, содержащей путь каталогаили файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

На входе: AH = 4Fh
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

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

Для работы с областью DTA MS-DOS имеет две функции. Это функция 2Fh , позволяющая получить адрес области DTA (она возвращает этот адрес в регистрах ES:BX ), и функция 1Ah , предназначенная для установки своей области DTA (адрес новой области DTA должен быть указан в регистрах DS:DX ).

Напомним, что по умолчанию область DTA занимает 128 байтов в префиксе сегмента программы PSP со смещением 80h .

В случае успешного поиска функции 4Eh и 4Fh помещают в DTA информацию о найденных файлах в следующем формате:

(0) 20 Зарезервировано.
(+21) 1 Атрибуты найденного файла
(+22) 2 Поле времени последнего обновления фалйла
(+24) 2 Поле даты последнего обновления фалйла
(+26) 4 Длина файла
(+30) 13 Имя файла и расширение в формате ASCIIZ

Номер начального класетра, распределенного файлу или каталогу, невозможно получить с помощью функций 4Eh и 4Fh .

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат две функции, предназначенные для сканирования каталогов — _dos_findfirst() и _dos_findnext() .

Приведем прототипы этих функций, описанные в файле dos.h :

В этих функциях параметр pattern определяет образец для поиска файлов, параметр attr — атрибуты файла — используется в качестве дополнительного критерия поиска. Параметр found представляет собой указатель на структуру, в которую будет записываться информация о найденных файлах. Эта структура определена в файле dos.h :

Приведем текст программы просмотра содержимого каталога. Программа принимает из командной строки параметр — образец для показа файлов. Если вы укажете параметр *.* , будет выведена информация обо всех файлах. Можно задавать полный путь: c:\*.* .

При запуске программы с параметром *.com на экран будет выведена информация:

В этом разделе мы рассмотрим функции MS-DOS, предназначенные для создания, переименования, удаления и перемещения файлов. Операции чтения из файла и записи в файл будут описаны в следующем разделе.

Для создания файла предназначена функция 3Ch прерывания INT 21h . С помощью этой функции может быть создан файл как в текущем, так и в любом другом каталоге. Если файл с указанным именем уже существует, он обрезается до нулевой длины. Будьте осторожны при использовании этой функции — она может уничтожить нужный вам файл.

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

Приведем формат вызова функции создания файла:

На входе: AH = 3Ch
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес строки, содержащей путь создаваемого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0.

При выполнении этой функции возможны следующие ошибки:

  • отсутствует какой-либо элемент в пути для создаваемого файла, например, диск или каталог;
  • была сделана попытка создать файл в корневом каталоге, но корневой каталог переполнен;
  • в указаннном каталоге уже есть файл с таким именем, и этот файл имеет атрибут «Только читаемый»;
  • пользователь, который работает в сети, не имеет прав доступа для выполнения указанной операции.

Операционная система игнорирует попытки создания с помощью этой функции каталогов или метки диска.

Для того, чтобы случайно не уничтожить содержимое файла с таким же именем, как и создаваемый, программа может использовать функцию 5Bh . Эта функция проверяет заданный путь на предмет наличия указанного файла. Если такой файл уже существует, функция возвращает программе признак ошибки.

Формат вызова функции:

На входе: AH = 5Bh
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес строки, содержащей путь создаваемого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0 .

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

На входе: AH = 5Ah
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес буфера, в который функция запишет путь созданного временного файла. Размер этого буфера должен быть по крайней мере 13 байтов.
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0 .

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

Перед тем, как начать работу с файлом, его нужно открыть. Функции, создающие новые файлы, открывают новые файлы автоматически. Для того, чтобы открыть существующий файл, вы можете воспользоваться функцией 3Dh :

На входе: AH = 3Dh
AL = Требуемый режим доступа:

Бит 7: флаг наследования

0 — файловый индекс наследуется порожденным процессом
1 — файловый индекс не наследуется порожденным процессом


Биты 4. 6: режим разделения

000 — режим совместимости
001 — запрещение всех видов доступа
010 — запрещение записи
011 — запрещение чтения
100 — разрешение всех видов доступа

Бит 3:0 — зарезервировано

Биты 0. 2: вид доступа

000 — чтение
001 — запись
010 — чтение/запись

DS:DX = Адрес строки, содержащей путь открываемого файла
На выходе: AX = Код ошибки, если флаг переноса CF был установлен в 1 ;
Файловый индекс, если флаг переноса сброшен в 0 .

С помощью функции 3Dh можно открыть любой файл (но не каталог). Если требуется вид доступа «запись», открываемый файл не должен иметь атрибут «Только читаемый».

Для использования битов 4. 7 (управляющих доступом к файлу другими программами в сети) должна быть запущена программа SHARE.EXE.

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

Операционная система MS-DOS версии 4.0 имеет в своем составе функцию 6Ch , обладающую расширенными возможностями по созданию и открытию файлов:

На входе: AH = 6Ch
AL = 00h
BX = байт флагов расширенного режима открытия файла
CX = атрибуты создаваемого файла, используется только при создании файлов
DX = выполняемая функция, если файл существует или не существует:

Биты 0-3 регистра DX задают действие, если файл существует:

0000h — если файл существует, вернуть признак ошибки
0001h — если файл существует, открыть его
0002h — если файл существует, заместить и открыть его

Биты 4-7 регистра DX задают действие, если файл не существует:

0000h — если файл не существует, вернуть признак ошибки
0001h — если файл не существует, создать и открыть его

DS:SI = Адрес строки, содержащей путь открываемого файла
На выходе: AX = Код ошибки, если флаг переноса CF был установлен в 1 ;
Файловый индекс, если флаг переноса сброшен в 0 .
CX = Код выполненных действий:
0 — файл был открыт
1 — файл был создан и открыт
2 — файл был замещен и открыт

Регистр BX на входе задает флаги расширенного режима открытия файла в следующем формате:

Биты Назначение
0. 2 Режим доступа при чтении/записи
3 Зарезервировано, должно быть равно 0
4. 6 Режим разделения
7 Флаг наследования
8. 12 Зарезервировано, должно быть равно 0
13 0 — Режим обычного использования обработчика критических ошибок INT 24h
1 — Блокировка обработчика критических ошибок INT 24h. Для того, чтобы узнать причину ошибки, программа должна использовать функцию 59h прерывания INT 21h MS-DOS.
14 Управление буферизацией:
0 — Использование стандартной для MS-DOS буферизации.
1 — Отмена буферизации. Использование этого режима замедлит работу с диском, однако вероятность потери информации при аварии в питающей сети уменьшится.

Описанная выше функция является как бы комбинацией функций 3Dh и 3Ch (открытие и создание файла). Она удобна, но при ее использовании программа должна убедиться в том, что версия используемой операционной системы не ниже, чем 4.0.

Удалить файл можно при помощи функции 41h прерывания INT 21h:

На входе: AH = 41h
DS:DX = Адрес строки в формате ASCIIZ, содержащей имя удаляемого файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

С помощью этой функции нельзя удалить файл, имеющий атрибут «Только читаемый».

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

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции для работы с файлами. Эти функции можно разделить на две группы — функции ввода/вывода низкого уровня и функции ввода/вывода потоком. Вторая группа функций использует буферизацию и будет рассмотрена в разделе, посвященном буферизованному вводу/выводу.

Функции ввода/вывода низкого уровня отображаются на описанные выше функции прерывания INT 21h (и функции этого же прерывания, предназначенные для чтения/записи, позиционирования и т.д.).

Для создания файла можно использовать функцию creat() :

Эта функция и ее параметры описаны в файлах io.h, sys\types.h, sys\stat.h, errno.h.

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

Второй параметр позволяет задать атрибуты создаваемого файла. Он может иметь следующие значения:

S_IWRITE для создаваемого файла разрешена операция записи;
S_IREAD для создаваемого файла разрешена операция чтения;
S_IREAD | S_IWRITE для создаваемого файла разрешены операции чтения и записи.

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

После создания файла функция creat() открывает новый файл и возвращает файловый индекс ( handle ) или код ошибки.

Мощная функция open() предназначена как для открытия существующих файлов, так и для создания новых:

Первый и третий параметры в этой функции аналогичны параметрам функции creat(), причем третий параметр нужен только при создании нового файла. Квадратные скобки указывают на то, что этот параметр является необязательным.

Параметр oflag может являться результатом битовой операции ИЛИ над следующими константами, определенными в файле fcntl.h:

O_APPEN при записи в файл информация будет добавляться в конец файла;
O_BINARY файл открывается для работы в двоичном режиме (игнорируются управляющие символы, такие как конец строки);
O_CREAT создается новый файл и открывается для записи; эта константа игнорируется, если указанный в первом параметре файл уже существует;
O_EXCL используется вместе с O_CREAT ; если указанный в первом параметре файл существует, функция возвратит признак ошибки;
O_RDONLY файл открывается только для чтения, попытка записи в файл приведет к тому, что функция записи вернет признак ошибки;
O_RDWR файл открывается как для чтения, так и для записи;
O_TEXT файл открывается в текстовом режиме;
O_TRUNC существующий файл открывается и обрезается до нулевой длины (если для этого файла разрешена операция записи);
O_WRONLY файл открывается только для записи (в операционных системах MS-DOS и OS/2 для файла, открытого с признаком O_WRONLY разрешено выполнение операции чтения).

Для того, чтобы закрыть файл, открытый функциями creat() или open() , нужно использовать функцию close():

В качестве параметра функции передается файловый индекс, полученный при открытии или создании файла. Функция возвращает 0 при успешном закрытии файла, или -1 при ошибке.

Код ошибки для этой и других функций cтандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0 записывается в глобальную переменную errno.

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

На входе: AH = 40h
BX = файловый индекс открытого файла
CX = количество записываемых байтов
DS:DX = Адрес буфера, содержащего записываемые данные
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Количество действительно записанных байтов, если флаг переноса CF сброшен в 0 .

При записи данные попадают в то место внутри файла, которое определяется содержимым так называемого файлового указателя позиции. При создании нового файла этот указатель сбрасывается в 0, что соответствует началу файла. При открытии файла с помощью функции 3Dh указатель также устанавливается на начало файла. Операция записи в файл с помощью функции 40h продвигает указатель вперед к концу файла на количество записываемых байтов.

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

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

Следует учитывать, что количество действительно записанных байтов может не совпадать с заданным в регистре CX при вызове функции 40h . Такая ситуация возможна, например, при записи в файл, открытый в текстовом режиме, байта Ctrl-Z (1Ah) . Этот байт означает конец текстового файла. Другая возможная причина — отсутствие свободного места на диске.

Если функция вызывается с содержимым регистра CX , равным 0 , файл будет обрезан или расширен до текущего положения файлового указателя.

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

Функция 40h может выполнять запись не только в файл, но и в устройство посимвольной обработки, предварительно открытое функцией 3Dh . Об этом мы говорили в разделах книги, посвященных драйверам.

Для чтения данных из файла (или устройства посимвольной обработки) предназначена функция 3Fh прерывания INT 21h :

На входе: AH = 3Fh
BX = файловый индекс открытого файла
CX = количество читаемых байтов
DS:DX = Адрес буфера для данных
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Количество действительно прочитанных байтов, если флаг переноса CF сброшен в 0 .

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

Если ваша программа составлена на языке программирования С, для записи и чтения данных она может воспользоваться функциями write() и read() :

Эти функции работают аналогично функциям 40h и 3Fh прерывания INT 21h . Параметр handle определяет файл, для которого необходимо выполнить операцию записи или чтения. Параметр buffer — указатель на буфер, который содержит данные для записи или в который необходимо поместить прочитанные данные. Количество записываемых/читаемых байтов определяется третьим параметром — count .

После выполнения операции функция возвращает количество действительно записанных или прочитанных данных или -1 при ошибке. Будьте внимательны, если вы записываете или читаете больше 32К байтов — вы можете получить признак ошибки, хотя передача данных выполнилась правильно. Большие массивы данных можно записывать по частям.

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

В приведенной программе для определения конца исходного файла использована функция eof():

Для файла с файловым индексом handle эта функция возвращает одно из трех значений:

1 достигнут конец файла;
конец файла не достигнут;
-1 ошибка, например, неправильно указан handle .

Программа, которая читает файл с помощью функции 3Fh прерывания INT 21h , может определить момент достижения конца файла, анализируя код ошибки в регистре AX .

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

Установить файловый указатель в нужную вам позицию можно с помощью функции 42h прерывания INT 21h MS-DOS:

На входе: AH = 42h
AL = метод кодирования:
00h абсолютное смещение от начала файла
01h смещение от текущей позиции
02h смещение от конца файла
BX = файловый индекс открытого файла
CX = старший байт смещения
DX = младший байт смещения
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Младший байт текущей позиции, если флаг переноса CF сброшен в 0.
DX = Старший байт текущей позиции

Функция позволяет указывать новое значение указателя либо как абсолютное смещение от начала файла, либо как смещение от текущей позиции, либо как смещение от конца файла. В последних двух случаях используется смещение со знаком. Для указания смещения или абсолютной позиции программа должна задать в регистрах CX, DX 32-битовое значение.

Если использовать метод кодирования 02h и задать нулевое смещение, функция установит указатель на конец файла. Это обстоятельство может быть использовано для определения размера файла в байтах.

Что произойдет, если при использовании методов кодирования 01h или 02h попытаться установить указатель позиции до начала файла?

Функция 42h при этом не возвратит признак ошибки, однако если будет сделана попытка прочитать или записать данные, то соответствующая функция чтения/записи завершится с ошибкой.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции, предназначенные для управления содержимым файлового указателя позиции и получения текущего значения этого указателя. Это функции lseek(), tell(), filelength() .

Функция lseek() работает аналогично только что описанной функции 42h . Приведем ее прототип:

Первый параметр определяет файл, для которого выполняется операция позиционирования. Параметр offset определяет смещение. Последний параметр задает метод кодирования смещения. Он может принимать следующие значения, описанные в фале stdio.h :

SEEK_SET Абсолютное смещение от начала файла
SEEK_CUR Смещение относительно текущей позиции
SEEK_END Смещение относительно конца файла

Функция возвращает величину текущего смещения в байтах относительно начала файла или -1L , в случае ошибки. Как и для остальных функций библиотеки С, код ошибки находится в глобальной переменной errno .

Вы, конечно, можете использовать функцию lseek() для определения размера файла или текущей файловой позиции. Однако для того, чтобы узнать размер файла, лучше воспользоваться специальной функцией filelength() :

Функция возвращает размер файла в байтах. Файл задается параметром handle . В случае ошибки функция возвращает значение -1L.

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

Эта функция возвращает текущую позицию для файла, определенного параметром handle , или -1L , в случае ошибки.

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

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

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

Для работы с полем атрибутов файла предназначена функция 43h прерывания INT 21h:

На входе: AH = 43h
AL = выполняемая операция:
00h чтение атрибутов файла
01h установка новых атрибутов файла
CX = новые атрибуты файла, если AL = 01h:
Биты:
5 — бит архивации
4 — каталог
3 — метка диска
2 — системный файл
1 — скрытый файл
0 — только читаемый файл
DS:DX = путь файла в формате ASCIIZ
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF
CX = Если не было ошибки, этот регистр содержит атрибуты файла

При изменении атрибутов файла допустимо указывать комбинации битов в регистре CX .

Если ваша программа работает в сети, она должна иметь соответствующие права доступа к каталогу, содержащему файл, для которого программа собирается изменять байт атрибутов.

Для работы с полями времени и даты последней модификации файла предназначена функция 57h прерывания INT 21h:

На входе: AH = 57h
AL = выполняемая операция:
00h чтение даты и времени
01h установка даты и времени
BX = файловый индекс открытого файла
CX = время
DX = дата
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF
CX = Если не было ошибки, этот регистр содержит время последнего изменения файла
DX = Если не было ошибки, этот регистр содержит дату последнего изменения файла

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

Формат поля времени:

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции для чтения и изменения атрибутов файлов и времени/даты их последней модификации.

Для определения атрибутов файла можно использовать функцию _dos_getfileattr() :

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

В случае успешного завершения функция возвращает 0 , в противном случае она возвращает код ошибки, полученный от операционной системы и устанавливает глобальную переменную errno в значение ENOENT , что означает отсутствие указанного в параметре path файла.

Для изменения атрибутов файла можно использовать функцию _dos_setfileattr():

Параметр attrib может принимать следующие значения:

_A_ARCH установка бита архивации
_A_HIDDEN файл скрытый
_A_NORMAL обычный файл
_A_RDONLY только читаемый файл
_A_SUBDIR каталог
_A_SYSTEM системный файл
_A_VOLID метка диска

Для определения времени последней модификации файла можно использовать функцию _dos_getftime():

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

Если вам надо изменить время или дату последней модификации файла, используйте функцию _dos_setftime():

Параметры этой функции аналогичны используемым в функции _dos_getftime() , за исключением того, что в качестве второго и третьего параметра применяются не указатели, а непосредственные значения даты и времени.

Приведем программу, изменяющую при запуске значение бита файла атрибутов «Только читаемый» для файла, имя которого передается программе в качестве параметра:

Программа сначала считывает байт атрибутов, затем инвертирует соответствующий бит и устанавливает новое значение байта атрибутов.


Ввод/вывод для дисков в операционной системе MS-DOS буферизован. Это означает, что данные не сразу записываются на диск, а накапливаются в специальном массиве (буфере). По мере заполнения буфер сбрасывается на диск. При чтении информация заполняет весь входной буфер, независимо от количества байтов, которые программа читает из файла. В дальнейшем, если программе потребуются данные, которые уже были считаны с диска и записаны во входной буфер, она получит данные непосредственно из этого буфера. Обращения к диску при этом не будет.

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

Операционная система MS-DOS имеет несколько буферов. Их количество зависит от оператора BUFFERS , находящегося в файле CONFIG.SYS . Этот оператор позволяет определить от 2 до 99 буферов. Если файл CONFIG.SYS не содержит оператора BUFFERS , по умолчанию используются два буфера.

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

Обычно для машин класса AT с диском размером 20-40 мегабайтов рекомендуется использовать 32 буфера, однако для каждого конкретного случая может потребоваться подбор этого параметра для оптимизации производительности системы.

Если ваша программа интенсивно использует обращение к каталогам файловой системы, вы можете использовать утилиту MS-DOS FASTOPEN , которая запоминает в оперативной памяти расположение на диске файлов и каталогов, уменьшая интенсивность обращения к диску. Например, при использовании следующей команды в оперативной памяти будет храниться информация о расположении максимально о 100 файлах и каталогах:

В операционной системе MS-DOS версии 4.0 вы можете указать для утилиты FASTOPEN опцию /X . Эта опция вызывает размещение информации о файлах и каталогах в дополнительной ( expanded ) памяти. Для этой версии операционной системы вызов утилиты FASTOPEN лучше всего выполнять через оператор INSTALL файла CONFIG.SYS:

В приведенной выше строке используются следующие обозначения:

d: обозначение диска;
n количество файлов или каталогов, для которых необходимо запомнить расположение, может иметь значение от 1 до 999, по умолчанию используется 34;
m количество буферов для фрагментированных файлов, может иметь значение от 1 до 999, по умолчанию используется 34;
/X задает расположение буферов в дополнительной памяти.

Еще один способ организовать буферизацию ввода/вывода для жестких дисков — использовать драйвер SMARTDRV.SYS. Этот драйвер позволяет создать для диска кэш-память в расширенной или дополнительной памяти. Например, следующая строка в файле CONFIG.SYS определяет дисковый кэш размером 530 килобайтов, размещенный в расширенной памяти:

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

Если вы используете кэш-память для диска, не следует задавать оператор BUFFERS в файле CONFIG.SYS или пользоваться утилитой FASTOPEN , так как это приведет к многократной буферизации и вызовет излишние пересылки данных в оперативной памяти.

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

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

На входе: AH = 68h
BX = файловый индекс открытого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
0 , если операция выполнена успешно.

Дополнительно обновляется дескриптор файла в каталоге, а именно поля времени, даты и размера файла.

Обратите также внимание на функцию расширенного открытия файлов 6Ch , входящую в состав MS-DOS версии 4.0. Эта функция позволяет при открытии файла отменить буферизацию.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат многочисленные функции, использующие собственный механизм буферизации при работе с файлами. Их часто называют функциями потокового ввода/вывода. Такую буферизацию не следует путать с буферизацией, выполняемой операционной системой. Имена всех этих функций начинаются на f — fopen(), fclose(), fprintf() и т.д.

Функции потокового ввода/вывода хорошо описаны во многих учебных пособиях по языку программирования Си, поэтому мы приведем лишь краткий обзор этих функций, делая акцент на особенностях их применения.

При использовании функций потокового ввода/вывода файлы открываются функцией fopen() , закрываются функцией fclose() . Эти функции не только открывают и закрывают файлы (получают и освобождают их файловый индекс), но и, соответственно, создают и уничтожают структуру типа FILE , описанную в файле stdio.h и связанную с данным файлом:

Для организации потокового ввода/вывода вначале необходимо при помощи функции fopen() открыть файл. Функция fopen() имеет следующий прототип:

Первый параметр указывает на строку, содержащую путь открываемого файла, второй — на строку режима открытия файла. Возможны следующие режимы:

«r» файл открывается для чтения;
«w» файл открывается для записи;
«a» файл открывается для записи, данные будут добавляться в конец файла.

К буквам r, w, a справа могут добавляться буквы t и b .

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

Строка режима открытия файла может дополнительно содержать символ ‘+’ . Этот символ означает, что для файла разрешены операции чтения и записи одновременно.

Для закрытия файлов, открытых для ввода/вывода потоком, должна использоваться функция fclose() :

При закрытии файла освобождаются и сбрасываются на диск все буфера, распределенные этому файлу.

Если вы открыли файл с помощью низкоуровневой функции open() , вы можете создать поток для этого файла, используя функцию fdopen():

В качестве первого параметра используется файловый индекс, полученный от функции open(), второй параметр аналогичен парметру mode для функции fopen() .

Для того чтобы закрыть поток, созданный функцией fdopen(), необходимо использовать функцию fclose() , а не close() .

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

Функция возвращает файловый индекс, связанный с данным потоком.

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

stdin стандартное устройство ввода;
stdout стандартное устройство вывода;
stderr стандартное устройство для вывода сообщений об ошибках;
stdaux стандартное последовательное устройство ввода/вывода;
stdprn стандартное печатающее устройство.

Для работы со стандартными устройствами ввода/вывода в библиотеках трансляторов для языка программирования Си имеется соответствующий набор функций, которые должны быть вам хорошо известны — printf(), scanf(), putchar() и т.д.. Мы не будем их описывать для экономии места.

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

Для записи данных в поток предназначена функция fwrite() :

Эта функция записывает в файл stream блоки информации, каждый из которых имеет длину size байтов. Количество блоков — count . Данные для записи расположены по адресу buffer .

Если файл открыт в текстовом режиме, каждый символ возврата каретки CR заменяется на два символа — возврата каретки CR и перевода строки LF .

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

Чтение данных потоком можно выполнить с помощью функции fread() :

Эта функция используется аналогично предыдущей. Для распознавания конца файла и обнаружения ошибок после вызова этой функции необходимо использовать функции feof() и ferror().

Если при использовании функции fread() вы задали значения параметров size или count , равные нулю, функция fread() не изменяет содержимое буфера buffer .

Для позиционирования внутри файла, открытого потоком с помощью функции fopen() , предназначена функция fseek() :

В этой функции параметр offset задает новое содержимое указателя текущей позиции в файле stream , а параметр origin — определяет способ задания новой позиции. Этот оператор может иметь значения, аналогичные используемым в функции lseek() :

SEEK_SET Абсолютное смещение от начала файла
SEEK_CUR Смещение относительно текущей позиции
SEEK_END Смещение относительно конца файла

При открытии файла указатель текущей позиции устанавливается на начало файла. Операции ввода/вывода вызывают увеличение значения этого указателя на количество прочитанных/записанных байтов.

Функция fseek() позволяет вам установить указатель за конец файла, однако при попытке установаит указатель до начала файла функция возвратит признак ошибки — ненулевое значение.

При использовании функции fseek() для позиционирования внутри файлов, открытых в текстовом режиме, необходимо учитывать особенность обработки текстовых файлов — автоматическую замену символа возврата каретки CR на пару символов: возврат каретки CR и перевод строки LF . Для текстовых файлов функция fseek() будет правильно работать только в следующих двух случаях:

  • поиск со смещением offset , равным нулю, при любом значении параметра origin ;
  • поиск выполняется относительно начала файла, причем в качестве смещения offset используется значение, полученное специальной функцией ftell() .

Функция ftell() возвращает текущее значение указателя позиции для файла, или -1 при ошибке:

Пара функций ftell() — fseek() позволит вам правильно организовать позиционирование для файлов, открытых в текстовом режиме.

Есть еще одна возможность организовать позиционирование внутри файлов, открытых потоком — использовать пару функций fgetpos() — fsetpos() :

Эти две функции используют для запоминания и установки позиции переменную с типом fpos_t, определенным в файле stdio.h. Функция fgetpos() записывает в эту переменную текущую позицию в потоке stream . Содержимое переменной затем может быть использовано для установки позиции в потоке с помощью функции fsetpos().

Обе эти функции возвращают нулевое значение в случае успешного завершения работы, или ненулевое — при ошибке.

Среди функций потокового ввода/вывода можно выделить группу функций форматного ввода/вывода. Это такие функции, как fputc(), fgetc(), fputs(), fgets(), fprintf(), fscanf() .

Функции форматного ввода/вывода сильно облегчают запись/чтение таких элементов данных, как отдельные байты, текстовые строки, числа в различных форматах.

Для записи в поток отдельных байтов используется функция fputc():

Байт c записывается в файл stream начиная с текущей позиции. После записи текущая позиция увеличивается на единицу. Функция возвращает записываемый байт или значение EOF , которое служит признаком ошибки.

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

Эта функция возвращает считанный из файла и преобразованный к типу int байт из потока stream . После чтения байта текущая позиция в файле увеличивается на единицу.

При достижении конца файла или в случае ошибок функция fgetc() возвращает значение EOF . Однако для проверки на ошибку или конец файла лучше пользоваться специальными функциями ferror() и feof() . Если вы открыли файл в двоичном режиме, единственный способ определить момент достижения конца файла — использовать функцию feof() , так как значение константы EOF может находиться в любом месте двоичного файла.

Для работы со строками предназначены функции fputs() и fgets() .

Функция fputs() предназначена для вывода строки в файл, открытый потоком:

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

Для ввода строк из текстового файла удобна функция fgets():

Функция читает байты из потока stream и записывает их в буфер string до тех пор, пока не произойдет одно из двух событий — будет прочитан символ новой строки ‘\n’ или количество прочитанных символов не будет равно n-1 .

После того, как байты будут прочитаны в буфер, в конец образованной из этих байтов строки функция записывает двоичный ноль. Если был прочитан символ новой строки ‘\n’ , он тоже записывается в буфер.

Для анализа достижения конца файла или ошибок необходимо использовать функции feof() и ferror() .

Для форматного вывода в файл содержимого переменных удобно использовать функцию fprintf() :

Эта функция аналогична хорошо известной вам функции форматного вывода на экран printf(), с которой обычно начинают изучение языка программирования Си. Вспомните такую программу:

Функция fprintf() имеет дополнительно один параметр — stream , который определяет выходной файл.

После завершения работы функция возвращает количество записанных байтов или отрицательную величину, если при записи произошла ошибка.

Для форматного ввода информации из файла можно использовать функцию fscanf() , аналогичную известной вам функции scanf():

Эта функция читает данные, начиная с текущей позиции в потоке stream , в переменные, определенные аргументами arg . Каждый аргумент должен являться указателем на переменную, соответствующую типу, определенному в строке формата format .

Функция fscanf() возвращает количество успешно считанных и преобразованных в указанный формат полей. Те поля, которые были считаны, но не преобразовывались, в возвращаемом функцией значении не учитываются.

При достижении конца файла функция возвращает значение EOF . Если функция возвратила нулевое значение, это означает, что преобразование полей не производилось.

Рассмотрим теперь функции, управляющие буферизацией для потокового ввода/вывода.

Функция setbuf() позволяет вам заменить системный буфер на свой собственный:

Параметр buffer должен указывать на подготовленный пользователем массив, имеющий размер BUFSIZ байтов. Константа BUFSIZ описана в файле stdio.h.

Функция setvbuf() позволяет программе не только указать свой буфер, но и задать его размер:

Параметр stream должен указывать на открытый поток, причем для этого потока до вызова функции setvbuf() нельзя выполнять операции чтения/записи.

Параметр buffer должен указыват на подготовленный программой буфер размером size байтов. Этот буфер будет использоваться для работы с потоком stream .

Параметр mode может иметь значения _IOFBF, _IOLBF, _IONBF . Если mode равно _IOFBF или _IOLBF , параметр size указывает размер буфера. Если параметр mode равен _IONBF , буферизация не используется, парметры buffer и size игнорируются.

Параметры _IOFBF и _IOLBF эквивалентны.

Если в качестве адреса буфера buffer задать значение NULL , функция автоматически закажет буфер размером size .

Функция setvbuf() возвращает ноль при успешном завершении и ненулевую величину, если указан неправильный парметр mode или неправильный размер буфера size .

Для чего может понадобиться изменение размера буфера?

Главным образом — для сокращения времени, необходимого для позиционирования магнитных головок при выполнении операций одновременно над несколькими файлами, например, при копировании файлов, слиянии нескольких файлов в один и т.д.

При закрытии потока функцией fclose() содержимое буфера записывается на диск. Если программе необходимо выполнить запись содержимого буфера на диск без закрытия файла, она может воспользоваться функцией fflush():

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

Если поток открыт только для чтения, функция fflush() очищает содержимое буфера, связанного с этим потоком.

В качестве примера приведем текст программы, копирующей содержимое текстового файла. Программа копирует этот файл три раза. В первый раз одна использует буфер стандартного размера, затем увеличивает размер буфера в десять раз, и, наконец, копирует файл без использования механизма буферизации. Каждый раз программа измеряет продолжительность копирования файла с помощью функции clock() , входящей в состав стандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0.

В задачу данной книги не входит описание всех функций стандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0, предназначенных для работы с дисками и файловой системой. Но мы приведем еще несколько интересных и полезных на наш взгляд функций.

Как мы уже отметили, программа может использовать два режима ввода/вывода для файлов — текстовый и двоичный. Для переключения этого режима для открытого файла можно использовать функцию setmode():


Первый параметр — файловый индекс. Второй параметр может принимать два значения:

O_TEXT установить текстовый режим;
O_BINARY установить двоичный режим.

Функция setmode() должна вызываться перед началом ввода/вывода в открытый файл.

Мы рассказывали о позиционировании внутри файла. Если вам нужно просто установить указатель позиции на начало файла, открытого для потокового ввода/вывода, вы можете воспользоваться функцией rewind():

Если вам нужно переназначить ввод/вывод для стандартных устройств (потоков stdin, stdout, stderr ), вы можете использовать функцию freopen() :

Функция freopen() закрывает файл, с которым был связан поток stream , и переназначает этот поток файлу, определенному параметром filename . Параметр mode задается так же, как и для функции fopen() .

Можно переназначить файловый индекс для файла, открытого функцией open() . Для этого можно воспользоваться одной из двух функций — dup() или dup2() :

Первая функция связывает с открытым файлом еще один файловый индекс. Этот индекс она возвращает при успешном завершении. В случае ошибки она возвращает значение -1 .

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

Функция dup2() переназначает файловый индекс handle2 , связывая его с тем же файлом, которому соответствует файловый индекс handle1 . Если во время вызова функции dup2() с файловым индексом handle2 связан какой-либо открытый файл, этот файл закрывается. В случае успешного завершения функция dup2() возвращает нулевое значение. Если произошла ошибка, возвращается значение -1 .

В первой книге при описании векторной таблицы связи мы говорили о том, что для всех открытых файлов MS-DOS хранит различную информацию в специальной таблице. Ее адрес находится в поле file_tab векторной таблицы связи.

В этой таблице для каждого открытого файла хранится информация о количестве файловых индексов ( file handle ), связанных с данным файлом, режиме открытия файла (чтение, запись и т.д.), слово информации об устройстве, указатель на заголовок драйвера, обслуживающего данное устройство, элемент дескриптора файла (дата, время, имя файла, номер начального кластера, распределенного файлу), номер последнего прочитанного кластера и т.д.

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

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

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

Файловая система ms-dos

Файл (по-английски file – папка, скоросшиватель) – это поименованная область памяти на каком-либо физическом носителе, предназначенная для хранения информации.

Совокупность средств MS-DOS, обеспечивающих доступ к информации на внешних носителях, называется системой управления файлами, илифайловой системой.

Одно из понятий файловой системы MS-DOS – логический диск. В некотором приближении можно считать, что с точки зрения MS-DOS каждый логический диск – это отдельный магнитный диск. Каждый логический диск имеет своеуникальное имя.

В качестве имени логического диска используются буквы английского алфавита от A до Z (включительно).

Таким образом, количество логических дисков, может быть не более 26.

Буквы A и B – отведены строго под имеющиеся в IBM PC дисководы.

Начиная с буквы C именуются логические диски (разделы)жесткого диска (рис. 1).

В случае, если данный IBM PC имеет только один FDD, буква B пропускается (см. рис. 2).

Как правило, только логические диски A и C могут быть системными.

Рис.1. Разделение на логические диски в системе с двумя дисководами.

Рис.2. Разделение на логические диски в системе с одним дисководом.

Файловая структура логического диска

Чтобы обратиться к информации на диске, находящейся в файле, надо знать физический адрес первого сектора (№ поверхности + № дорожки + № сектора), общее количество кластеров, занимаемое данным файлом, адрес следующего кластера, если размер файла больше, чем размер одного кластера и т.д. Все это очень туманно, трудно и не нужно.

MS-DOS избавляет пользователя от такой работы и ведет ее сама.

Для обеспечения доступа к файлам файловая система MS-DOS организует и поддерживает на логическом диске определенную файловую структуру (рис.3).

Элементы файловой структуры:

– стартовый сектор(сектор начальной загрузки, Boot-сектор);

– таблица размещения файлов (FAT – File Allocation Table);

– корневой каталог(Root Directory);

– область данных (оставшееся свободным дисковое пространство).

Эти элементы создаются специальными программами в среде MS-DOS в процессе инициализации диска.

Рис.3. Файловая структура на дискете емкостью 360 кбайт

За стартовым сектором располагается FAT.

FAT (таблица размещения файлов)

Область данных диска представлена в MS-DOS как последовательность пронумерованных кластеров.

FAT– это массив элементов, адресующих кластеры области данных диска. Каждому кластеру области данных соответствует один элемент FAT. Элементы FAT служат в качестве цепочки ссылок на кластеры файла в области данных.

FAT– крайне важный элемент файловой структуры. Нарушения в FAT могут привести к полной или частичной потери информации на всем логическом диске. Именно поэтому, на диске хранится две копии FAT. Существуют специальные программы, которые контролируют состояние FAT и исправляют нарушения.

Корневой Каталог. Это определенная область диска, создаваемая в процессе инициализации (форматировании) диска, где содержится информация о файлах и каталогах, хранящихся на диске. Корневой каталог всегда существует на отформатированном диске. На одном диске бывает только один корневой каталог. Размер корневого каталога для данного диска – величина фиксированная, поэтому максимальное количество «привязанных» к нему файлов и других (дочерних) каталогов (подкаталогов) – строго определенное.

Каталоги (подкаталоги).Каталог – это определенное место на диске (в области данных диска), где содержится информация о файлах и подкаталогах, привязанных к данному каталогу.

MS-DOS поддерживает иерархическую структуру каталогов (древообразную, см. рис.4).

Рис.4. Иерархическая структура каталогов

В отличие от корневого каталога, остальные каталоги (подкаталоги) создаются с помощью команд MS-DOS. Основная цель такой структуры каталогов – организация эффективного хранения большого количества файлов на диске.

Каждый каталог, кроме корневого, имеет «родителя», т.е. другой каталог, в котором зарегистрирован данный каталог. MS-DOS рассматривает каждый каталог, кроме корневого, как файл.

Ф айлы.Файл – это поименованная область памяти на каком-либо физическом носителе, предназначенная для хранения информации. Файл всегда зарегистрирован в каком-либо каталоге, в том числе, может быть «привязан» и к корневому каталогу (см. рис.5).

Рис.5. Иерархическая структура каталогов с файлами

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

Файловая система MS-DOS не допускает, чтобы логические диски, каталоги, файлы были с одинаковыми ИДЕНТИФИКАТОРАМИ!

В качестве имени логического диска используется одна из букв латинского алфавита (A . Z). Каждый файл или каталог, кроме корневого, имеет полное имя.

Полное имя файла состоит из следующих частей (рис.6):

– имя логического диска (A … Z);

– символ, идентифицирующий корневой каталог – ‘\’ (слэш);

– перечень каталогов и подкаталогов (разделенных символом ‘\’);

– собственно имя файла.

Рис.6. Полное имя файла

Собственно имя файла состоит из имени, символа-разделителя ‘.’ (точка) и расширения имени файла.

Маршрут доступа к файлу = «Имя логического диска» + «двоеточие» + «идентификация корневого каталога» + «весь перечень имен родительских каталогов».

Максимальное количество символов в полном имени файла равно 128.

Максимальное количество символов в имени файла равно 8.

Максимальное количество символов в расширении имени файла равно 3.

Расширение не обязательно, т.е. может и не присутствовать (в этом случае точка тоже отсутствует). Таким образом, размер собственно имени файла не превышает 13 символов (с учетом точки).

В полном имени файла разрешается использовать только следующие символы: A…Z, a … z, 0 … 9, $, &, #, `,

В полном имени файла запрещается использовать все остальные символы.

Примеры допустимых имен файлов:

format.COM read.me myfile.txt 28-03-96.doc 123.45

Примеры не допустимых имен файлов:

123456789.txt aa?.doc 35*.? i\t.f.doc *.txt my:file.txt

Использование расширений.Файлы, в зависимости от информации которая там хранится, могут иметь различное назначение: данные, программы, драйверы, настроечные файлы и т.д.

Расширения имени файла – не обязательный, но очень важный компонент. Он используется для разделения файлов по отдельным категориям (данные, программы, драйверы и т.д.).

В MS-DOS есть перечень предопределенных и наиболее часто встречающихся расширений файлов. В табл.1приведены некоторые из них.

Выполняемые файлы в MS-DOS – это программы, созданные с помощью специальных инструментальных систем программирования, базирующиеся на применении языков программирования

Файл последовательности команд MS-DOS (пакетный)

Системный файл или файл драйвера устройств

Резервная (предыдущая) копия файла

Файл-документ MS Word

Текст программы на языке программирования Pascal

Тексты программ на языках программирования С, С++

Текст программы на языке Ассемблер.

Файл изображения в формате Windows BitMaP

Файл точечного изображения (Graphic Interchange Format)

Файл изображения в формате Paintbrush

Файл изображения (Tagged Image File Format)

Файлы настроек и конфигураций

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

Асинхронный интерфейс (Auxiliary – вспомогательный выход)

Консоль (клавиатура, дисплей)

Первый порт последовательного ввода/вывода (от COMmunication)

Второй порт последовательного ввода/вывода

Третий порт последовательного ввода/вывода

Четвертый порт последовательного ввода/вывода

Первый порт параллельного ввода/вывода (от Line PrinTer 1)

Второй порт параллельного ввода/вывода


Третий порт параллельного ввода/вывода

Отсутствующий выход («нулевое устройство»)

Принтер (от PRiNter – аналог LPT1)

С точки зрения пользователя эти устройства ничем не отличаются от обычных файлов (с ними можно производить все те же операции, что и с обычными файлами). Однако не рекомендуется использовать имена файлов, построенные на базе вышеприведенных зарезервированных имен, такие, как: NUL.BAT, COM2.COO, PRN. TXT и т.п. Использование их в качестве расширений имен файлов допустимо: TEXT.PRN, FILE1.CON, FILE.NUL и т.п.

Символы подстановки в именах файлов.Когда необходимо произвести какие-либо действия над файлами пользователь вызывает определенные внутренние или внешние команды MS-DOS и передает им в качестве параметров имена файлов. Очень часто приходится производить одни и те же действия над многими файлами. Например, необходимо скопировать все файлы какого-либо каталога в другой каталог. Если файлов больше 200, то ровно 200 раз необходимо произвести эту операцию для каждого файла в отдельности. Это, как минимум, неудобно и непроизводительно для пользователя. Для решения такого рода проблем существуют специальные средства, которые помогают производить однотипные операции над целой группой файлов одной командой.

Так называемые символы подстановки, называемые также масками (по-английски они называются wildcards), позволяют фильтровать файлы, выполняя функцию обозначения места в имени файла. Такими масками являются знак вопроса(?) и звездочка (*).

Эти символы можно использовать в любом месте собственно имени файла и расширения. Символ ? означает, что команда при фильтрации файлов признает любой символ в имени или расширении файла, в позиции которого находится символ ?.

Символ * означает, что команда при фильтрации файлов признает все символы, в имени или расширении файла, начиная с позиции, где находится символ *.

Символы ? и * действуют не зависимо друг от друга применительно к имени или расширению.

Выполнить операцию над следующими группами файлов:

*.* – все файлы, без исключения;

*.txt – файлы с любыми именами, но с расширением txt;

II*.* – файлы, имена которых начинаются с цепочки символов II и имеющие любое расширение;

YE??0198.* – файлы, имена которых начинаются с цепочки символов YE, два следующих символа могут быть любыми, следующие четыре символа должны быть 0198, расширение любое.

Атрибуты файлов.Каждый файл и каталог имеет атрибут, который указывает на то, что этот файл является именно файлом, или на то, что он является каталогом. Файлы, в зависимости от атрибута, могут быть скрытыми, архивными, системными, только для чтения.

Dos fn 32h: дать информацию dos о диске

Плохо смотрел значит, там все что нужно есть, даже больше чем тебе сейчас нужно знать

═══════════════════════════════════ ════════════════════╡ Функции DOS │
DOS Fn 00H: Завершить программу
DOS Fn 01H: Ввод с клавиатуры
DOS Fn 02H: Вывод на дисплей
DOS Fn 03H: Ввод AUX
DOS Fn 04H: Вывод AUX
DOS Fn 05H: Вывод на принтер
DOS Fn 06H: Обмен с консолью
DOS Fn 07H: Нефильтрующий консольный ввод без эха
DOS Fn 08H: Консольный ввод без эха
DOS Fn 09H: Выдать строку
DOS Fn 0aH: Буферизованный ввод строки
DOS Fn 0bH: Проверить статус ввода
DOS Fn 0cH: Ввод с очисткой
DOS Fn 0dH: Сбросить диск
DOS Fn 0eH: Выбрать умалчиваемый диск DOS
DOS Fn 0fH: Открыть файл через FCB
DOS Fn 10H: Закрыть файл через FCB
DOS Fn 11H: Найти 1-й совпадающий файл через FCB
DOS Fn 12H: Найти следующий совпадающий файл через FCB
DOS Fn 13H: Удалить файл через FCB
DOS Fn 14H: Читать последовательный файл через FCB
DOS Fn 15H: Писать последовательный файл через FCB
DOS Fn 16H: Создать файл через FCB
DOS Fn 17H: Переименовать файл через FCB
DOS Fn 19H: Дать умалчиваемый диск DOS
DOS Fn 1aH: Установить адрес DTA
DOS Fn 1bH: Дать информацию FAT (текущий диск)
DOS Fn 1cH: Дать информацию FAT (любой диск)
DOS Fn 21H: Читать запись произвольного файла
DOS Fn 22H: Писать запись произвольного файла
DOS Fn 23H: Дать размер файла через FCB
DOS Fn 24H: Установить адрес блока произвольного файла
DOS Fn 25H: Установить вектор прерывания
DOS Fn 26H: Создать префикс программного сегмента
DOS Fn 27H: Читать блок произвольного файла
DOS Fn 28H: Писать блок произвольного файла
DOS Fn 29H: Разобрать имя файла
DOS Fn 2aH: Дать дату DOS
DOS Fn 2bH: Установить дату DOS
DOS Fn 2cH: Дать время DOS
DOS Fn 2dH: Установить время DOS
DOS Fn 2eH: Установить/сбросить переключатель верификации
DOS Fn 2fH: Дать текущий DTA
DOS Fn 30H: Дать номер версии DOS
DOS Fn 31H: Завершиться и остаться резидентным — KEEP
DOS Fn 32H: Дать дисковую информацию DOS (недокументировано)
DOS Fn 33H: Установить/опросить уровень контроля прерывания DOS
DOS Fn 34H: Адрес статуса реентерабельности DOS
DOS Fn 35H: Дать вектор прерывания
DOS Fn 36H: Дать свободную память диска
DOS Fn 37H: Установить/опросить символ-переключатель (недокументировано)
DOS Fn 38H: Дать/Установить информацию страны
DOS Fn 39H: Создать новое оглавление — MKDIR
DOS Fn 3aH: Удалить оглавление — RMDIR
DOS Fn 3bH: Установить умалчиваемое оглавление DOS — CHDIR
DOS Fn 3cH: Создать описатель файла
DOS Fn 3dH: Открыть описатель файла
DOS Fn 3eH: Закрыть описатель файла
DOS Fn 3fH: Читать файл через описатель
DOS Fn 40H: Писать в файл через описатель
DOS Fn 41H: Удалить файл
DOS Fn 42H: Установить указатель файла — LSEEK
DOS Fn 43H: Установить/опросить атрибут файла — CHMOD
DOS Fn 44H: Управление вводом-выводом устройства — IOCTL
DOS Fn 45H: Дублировать описатель файла — DUP
DOS Fn 46H: Переназначить описатель — FORCDUP
DOS Fn 47H: Дать умалчиваемое оглавление DOS
DOS Fn 48H: Распределить память (дать размер памяти)
DOS Fn 49H: Освободить блок распределенной памяти
DOS Fn 4aH: Сжать или расширить блок памяти
DOS Fn 4bH: Выполнить или загрузить программу — EXEC
DOS Fn 4cH: Завершить программу — EXIT
DOS Fn 4dH: Дать код выхода программы — WAIT
DOS Fn 4eH: Найти 1-й совпадающий файл
DOS Fn 4fH: Найти следующий совпадающий файл
DOS Fn 54H: Дать переключатель верификации DOS
DOS Fn 56H: Переименовать/переместить файл
DOS Fn 57H: Установить/опросить время/дату файла
DOS Fn 59H: Дать расширенную информацию об ошибке
DOS Fn 5aH: Создать уникальный временный файл
DOS Fn 5bH: Создать новый файл
DOS Fn 5cH: Блокировать/разблокировать доступ к файлу
DOS Fn 5eH: Различные сетевые функции
DOS Fn 5fH: Переназначение устройств в сети
DOS Fn 62H: Дать адрес префикса программного сегмента
═══════════════════════════════════ ════════════════════╡ Прерывания DOS
INT 20H: Завершить программу
INT 21H: Функции DOS
INT 22H: Адрес завершения
INT 23H: Адрес выхода по Ctrl-Break
INT 24H: Обработчик критических ошибок
INT 25H/26H: Прямые дисковые чтение/запись
INT 27H: Завершиться и остаться резидентным
INT 28H: Квант времени DOS (недокументировано)
INT 2eH: Выполнить команду DOS (недокументировано)
INT 2fH: Мультиплексное прерывание

Выходим в DOS, в нормальный, чистый DOS

Иногда нужно заргузится в DOS, например для того чтобы запустить систему диагностики hdd (типа mhdd) или посмотреть 256 байтную демку. Но не нужно судорожно перерывать чердак в поисках старой дискетки и продувать дисковод, не нужно даже переразмечать разделы на hdd для fat16, даже не надо портить болванку и искать олдскульного друга с чернобелым монитором, 386 процессором и большой бородой.
Дос вполне можно загрузить через memdisk.

1) Ставим пакет syslinux
2) Находим файл memdisk из этого пакета (у меня он был в /usr/share/syslinux)
3) Копируем memdisk в /boot
4) Берём образ дискетки с msdos (можно у меня, уже с mhdd и демкой puls)
5) Копируем образ тоже в /boot
6) Дополняем /boot/grub/menu.lst таким пунктом:
title MSDOS
root(hd0,0) # Номер диска изменить на нужный
kernel /memdisk
initrd /Dos6.22.img
7) Перезагружаемся и ностальгируем

UPD: Я знаю что есть 9000 способов загрузится в дос сидюка, флешки, зипа, стриммера, перфокарты, однако это всё требует дополнительного оборудования и носителей. Данный способ не требует ничего, кроме установленного grub и интернета.

UPD/2: Таким способом можно диагностировать винт на котором находится сам образ mhdd.

Приложение Б Функции DOS (INT 21h)

Приложение Б Функции DOS (INT 21h)

DOS, функция 00h

CS – сегмент PSP завершающегося процесса

Описание. Передает управление на вектор завершения в PSP (выходит в родительский процесс). Идентична функции INT 20h (Terminate). Регистр CS должен указывать на PSP. Восстанавливает векторы прерываний DOS 22h-24h (Завершение, Ctrl-Break и Критическая ошибка), устанавливая значения, сохраненные в родительском PSP. Выполняет сброс файловых буферов. Файлы должны быть предварительно закрыты, если их длина изменилась.

Данная функция не рекомендуется к использованию. Для выхода из программы лучше использовать функцию DOS 4Ch.

DOS, функция 01h Считать со стандартного устройства ввода

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

Описание. Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). При обнаружении Ctrl-Break выполняется INT 23h.

Ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и другие) требует двух обращений к этой функции. Первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.

DOS, функция 02h Записать в стандартное устройство вывода

DL – символ, выводимый в стандартный вывод

Посылает символ из DL в стандартное устройство вывода. Обрабатывает символ Backspace (ASCII 8), перемещая курсор влево на одну позицию и оставляя его в новой позиции. При обнаружении Ctrl-Break выполняется INT 23h.

DOS, функция 03h Считать символа со стандартного вспомогательного устройства

Выход: AL – символ, введенный со стандартного вспомогательного устройства

Описание. Считывает (ожидает) символ со стандартного вспомогательного устройства, COM1 или AUX и возвращает этот символ в AL.

Ввод не буферизуется и должен опрашиваться (не управляется прерываниями). При запуске DOS порт AUX (COM1) инициализируется так: 2400 бод, без проверки на четность, 1 стоп-бит, 8-битные слова. Команда DOS MODE используется для установки иных характеристик.

DOS, функция 04h Записать символ в стандартное вспомогательное устройство

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

Посылает символ, находящийся в регистре DL, на стандартное вспомогательное устройство, COM1 или AUX.

DOS, функция 05h Вывести на принтер

DL – символ, записываемый на стандартный принтер

Посылает символ в DL на стандартное устройство печати, обычно LPT1.

DOS, функция 06h Консольный ввод-вывод

DL=00h-FEh – символ, посылаемый на стандартный вывод

DL=FFh – запрос ввода со стандартного ввода

ZF=0, если осуществлялся ввод символа и символ готов при запросе ввода

AL – считанный символ

ZF=1, если осуществлялся ввод символа и символа в консоли нет

При DL=0FFh выполняет ввод с консоли «Без ожидания», возвращая включенный флаг нуля ZF, если на консоли нет готового символа. Если символ готов, сбрасывает флаг ZF и возвращает считанный символ в AL. Если DL не равен 0FFh, то DL направляется на стандартный вывод.

DOS, функция 07h Нефильтрующий консольный ввод без эха

Выход: AL – символ, полученный через стандартный ввод

Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не проверяет на Ctrl-Break, BackSpace и другие.

Для ввода расширенного символа ASCII должна быть вызвана дважды. Для проверки статуса используется функция DOS 0Bh (чтобы не ожидать нажатия клавиши).

DOS, функция 08h Консольный ввод без эха

Выход: AL – символ, полученный через стандартный ввод

Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23h.

Для ввода расширенного символа ASCII должна быть вызвана дважды.

DOS, функция 09h Запись строки на стандартный вывод

DS:DX – адрес строки, заканчивающейся символом «$» (ASCII 24h)

Строка, исключая завершающий ее символ «$», посылается на стандартный вывод. Символы Backspace обрабатываются как в функции 02h (вывод на дисплей). Чтобы перейти на новую строку, обычно включают в текст пару CR/LF (ASCII 0Dh и ASCII 0Ah). Строки, содержащие «$», можно передать на стандартное устройство вывода с помощью функции 40h (BX=0).

DOS, функция 0Ah Ввод строки в буфер

DS:DX – адрес входного буфера (Таблица Б-1)

Таблица Б-1. Формат входного буфера

Буфер содержит введенные данные, в конце – символ CR (ASCII 0Dh)

DOS, функция 0Bh Проверка статуса ввода

Выход: AL=FFh, если символ доступен со стандартного ввода AL=00h, если нет доступного символа

Описание. Проверяет состояние стандартного ввода. При распознавании Ctrl-Break выполняется INT 23h.

Используется перед функциями 01h, 07h и 08h, чтобы избежать ожидания нажатия клавиши.

Эта функция дает простой неразрушающий способ проверки Ctrl-Break в процессе длинных вычислений или другой обработки, обычно не требующей ввода. Это позволяет снимать счет по нажатию Ctrl-Break.

DOS, функция 0Ch Ввод с очисткой

AL – номер функции ввода DOS:

AL=01h – ввод с клавиатуры

AL=06h – ввод с консоли

AL=07h – нефильтрующий без эха

AL=08h – ввод без эха

AL=0Ah – буферизованный ввод

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

DOS, функция 0Dh Сброс диска

Сбрасывает диск (записывает на диск все файловые буферы). Файл, размер которого изменился, должен быть предварительно закрыт (при помощи функций 10h или 3Eh).

DOS, функция 0Eh Установить текущий диск DOS

DL – номер диска (0 – A, 1 – B и так далее), который становится текущим

Выход: AL – общее число дисководов в системе

Описание. Диск, указанный в DL, становится текущим. Проверка: используется функция 19h (дать текущий диск). В регистре AL возвращается число дисководов всех типов, включая жесткие диски и «логические» диски (как диск B: системе с одним гибким диском).

AL имеет то же значение, что и LASTDRIVE, указанное в файле CONFIG.SYS, и по умолчанию равно 5.

DOS, функция 0Fh Открыть файл через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

Таблица Б-2. Формат FCB

AL=00h, если функция выполнена успешно (FCB заполнен)

AL=FFh, если файл не найден или доступ к файлу не разрешен

Файл, описываемый неоткрытым FCB, должен существовать в текущем оглавлении на диске, специфицированном в FCB (0 – текущий, 1 – A, 2 – B и так далее). Если файл не существует, возвращается AL=0FFh. Файл открывается в режиме совместимости. Если поле «Номер диска» в FCB равно нулю в момент вызова, то оно заполняется номером текущего дисковода (1 – A, 2 – B и так далее). Поле FCB «Номер текущего блока» устанавливается в ноль. Поле FCB «Размер логической записи» устанавливается в 80h. Поля даты и размера файла в FCB устанавливаются из оглавления.

DOS, функция 10h Закрыть файл через FCB

DS:DX – адрес открытого FCB (Таблица Б-2)


AL=00h, если функция выполнена успешно

AL=FFh, если файл не найден там, где он находился при открытии с помощью функции 0Fh

Закрывает файл, открытый функцией 0Fh. Файл должен находиться на своем первоначальном месте в текущем оглавлении диска, на котором он был открыт. Если файл найден, оглавление обновляется, файловые буфера сбрасываются и возвращается AL=00h. Если файл не найден, оглавление не обновляется и возвращается AL=FFh.

DOS, функция 11h Найти первый совпадающий файл через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

AL=00h, если подходящее имя найдено

AL=FFh, если подходящего имени нет

В текущем оглавлении DOS происходит поиск файлов с именем, соответствующим заданному шаблону. При неудаче возвращается AL=0FFh. Если имя найдено, AL очищается, в первый байт DTA помещается номер дисковода (A – 1, B – 2 и так далее), а в следующие 32 байта помещается элемент оглавления для найденного файла.

Можно использовать при вызове расширенный FCB, чтобы выбирать файлы с указанными атрибутами. В этом случае в DTA помещаются: байт FFh, 7 байт нулей, номер диска и элемент оглавления.

DOS, функция 12h Найти следующий совпадающий файл через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

AL=00h, если подходящее имя найдено

DTA заполнен AL=FFh, если подходящего имени нет

Используется после вызова функции 11h (Найти первый совпадающий файл через FCB) с обобщенным именем файла. Каждый последующий вызов заполняет DTA очередным подходящим элементом оглавления и возвращает AL=00h. Если подходящих имен больше нет, возвращается AL=FFh.

Резервируемая область в FCB сохраняет информацию, необходимую для продолжения поиска. Поэтому не стоит открывать и изменять FCB между вызовами.

DOS, функция 13h Удалить файл через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

AL=00h, если функция выполнена успешно

AL=FFh, если файл не найден или доступ к файлу не разрешен

Эта функция удаляет все подходящие файлы в текущем оглавлении указанного диска согласно спецификации в FCB. Если подходящие файлы не найдены или если доступ отвергнут (как при попытке удалить файл с атрибутом Read-Only), функция возвращает в регистре AL значение FFh.

DOS, функция 14h Последовательное чтение из файла через FCB

DS:DX – адрес открытого FCB (Таблица Б-2)

AL=00h, если чтение было успешным и DTA содержит данные

AL=01h, если достигнут конец файла (EOF) и данные не считаны

AL=02h, если произошел выход за сегмент (чтения не было)

AL=03h, если EOF и считана усеченная запись (дополнена нулями)

Функция читает файл, специфицированный в FCB. Затем соответственно увеличивает значения полей в FCB.

Перед началом последовательной обработки файла нужно сбрасывать CurRec в ноль, так как функция 0Fh не инициализирует это поле.

DOS, функция 15h Последовательная запись в файл через FCB

DS:DX – адрес открытого FCB (Таблица Б-2)

AL=00h, если запись была успешной

AL=01h, если ошибка переполнения диска (данные не записаны)

AL=02h, если произошел выход за сегмент (записи не было)

Функция записывает файл, специфицированный в FCB. Затем соответственно увеличивает значения полей в FCB.

Перед началом последовательной обработки файла нужно сбрасывать «Номер текщей записи» в ноль, так как функция 0Fh не инициализирует это поле.

DOS буферизует данные, записывая полный сектор за один раз.

DOS, функция 16h Создание файла через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

AL=00h, если функция выполнена успешно FCB заполнен

AL=FFh, если при выполнении функции возникли ошибки

Описание. Файл, специфицированный неоткрытым FCB, создается на диске, указанном в FCB (0 – текущий, 1 – A и так далее). Он открывается в текущем оглавлении этого диска. FCB заполняется аналогично функции 0Fh. Если файл существует в момент вызова, его элемент оглавления перекрывается новым файлом, а длина файла сбрасывается в ноль.

Handle-ориентированные функции DOS 2.0+ гораздо удобнее в работе.

DOS, функция 17h Переименовать файл через FCB

DS:DX – адрес измененного FCB (Таблица Б-2)

AL=00h, если функция выполнена успешно

AL=FFh, если при выполнении функции возникли ошибки

Переименовывает файл в текущем оглавлении.

DOS, функция 19h Получить текущий диск DOS

Выход: AL – номер текущего диска (0 – A, 1 – B, и так далее)

Возвращает номер дисковода текущего диска DOS.

DOS, функция 1Ah Установить адрес DTA

DS:DX – адрес DTA

Устанавливает адрес DTA. Все FCB-ориентированные операции работают с DTA. DOS не позволяет операциям ввода/вывода пересекать границу сегмента. Функции поиска 11h, 12h, 4Eh и 4Fh помещают данные в DTA. DTA глобальна, поэтому надо проявлять осторожность при назначении ее в рекурсивной процедуре. При запуске программы ее DTA устанавливается по смещению 80h относительно PSP.

DOS, функция 1Bh Получить информацию FAT для текущего диска

DS:BX – адрес байта FAT ID, отражающего тип диска (Таблица Б-3)

DX – всего кластеров (единиц распределения) на диске

AL – секторов на кластер

CX – байт на сектор

Таблица Б-3. Значения >

Возвращает информацию о размере и типе текущего диска. Размер диска (в байтах) равен DX*AL*CX. Свободную память можно найти функциями 36h или 32h.

Версии: DOS 1.x держит FAT в памяти и возвращает DS:BX => FAT. DOS 2.0+ может держать в памяти лишь часть всей FAT.

Эта функция изменяет содержимое регистра DS.

DOS, функция 1Ch Получить информацию FAT для указанного диска

DL – номер диска (0 – текущий, 1 – A и так далее)

DS:BX – адрес байта FAT ID, отражающего тип диска (приведен в описании функции 1Bh)

DX – всего кластеров (единиц распределения)

AL – секторов на кластер

CX – байт на сектор

Аналогична функции 1Bh с той разницей, что регистр DL указывает диск, для которого нужно получить информацию.

DOS, функция 21h Считать произвольную запись файла

DS:DX – адрес открытого FCB (Таблица Б-2)

AL=00h, если чтение было успешным и DTA заполнена данными

AL=01h, если достигнут конец файла (EOF) и чтения не было

AL=02h, если произошел выход за сегмент (чтения нет)

AL=03h, если встречен EOF и усеченная запись дополнена нулями

Данная функция читает из файла с текущей позиции как с указанной в полях FCB «Запись с текущей позиции» и «Номер записи при непосредственном доступе к файлу».

DOS, функция 22h Писать произвольную запись файла

DS:DX – адрес открытого FCB (Таблица Б-2)

AL=00h, если запись была успешной

AL=01h, при переполнении диска

AL=02h, если DTA+FCB выходит за сегмент (нет записи)

Данная функция записывает в файл с текущей позиции как с указанной в полях FCB «Запись с текущей позиции» и «Номер записи при непосредственном доступе к файлу».

DOS, функция 23h Получить размер файла через FCB

DS:DX – адрес неоткрытого FCB (Таблица Б-2)

AL=00h, если функция выполнена успешно

AL=FFh, если при выполнении функции возникли ошибки

Проще определить размер файла при помощи функции 3Dh с последующим выполнением 42h (при AL=2).

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

DS:DX – адрес открытого FCB (Таблица Б-2)

Устанавливает поле «Номер записи при непосредственном доступе к файлу» в FCB на файловый адрес, соответствующий значениям полей «Текущий блок» и «Запись с текущей позиции».

DOS, функция 25h Установить вектор прерывания

AL – номер прерывания

DS:DX – вектор прерывания – адрес программы обработки прерывания

Описание. Устанавливает значение элемента таблицы векторов прерываний для прерывания с номером AL, равным DS:DX. Это равносильно записи 4-байтового адреса в 0000:(AL*4), но, в отличие от прямой записи, DOS знает, что происходит, и гарантирует, что в момент записи прерывания будут заблокированы.

Восстановить DS (если необходимо) после этого вызова.

DOS, функция 26h Создать новый PSP


DX – адрес сегмента (параграфа) для нового PSP

CS – сегмент PSP, используемый как шаблон для нового PSP (Таблица Б-4)

Описание. Устанавливает PSP для порождаемого процесса по адресу DX:0000. Текущий PSP (100h байт, начиная с CS:0) копируется в DX:0000h, поле MemTop соответственно корректируется, векторы Terminate, Ctrl-Break и Critical Error копируются в PSP из векторов прерываний INT 22h, INT 23h и INT 24h. После этого можно загрузить программу с диска и передать ей управление посредством FAR JMP.

Если перехватывается INT 21h, нужно позаботиться о помещении в стек корректного CS: IP. Еще лучше использовать функцию 4Ch.

Таблица Б-4. Формат PSP

DOS, функция 27h Читать произвольный блок файла

DS:DX – адрес открытого FCB (Таблица Б-2)

CX – число считываемых записей

Выход: AL=00h, если чтение успешно и DTA заполнена данными AL=01h если достигнут конец файла (EOF) и данные не считаны AL=02h, если при чтении произошел выход за границу сегмента AL=03h, если EOF и считана усеченная порция (дополнена нулями) CX – действительное число считанных записей

Читает несколько записей из файла, начиная с файлового адреса, указанного полем «Номер записи при непосредственном доступе к файлу» в FCB. Помещает данные в память, начиная с адреса DTA. Соответствующие поля FCB корректируются, чтобы указывать на следующую запись (первую за прочитанными).

DOS, функция 28h Писать произвольный блок файла

DS:DX – адрес открытого FCB (Таблица Б-2)

CX – число записываемых блоков (если CX равен нулю, то размер файла усекается до указанного в поле FCB «Номер записи при непосредственном доступе к файлу»)

AL=00h, если запись успешна

AL=01h, при переполнении диска

AL=02h, если при записи произошел выход за границу сегмента

CX – действительное число сделанных записей

Описание. Записывает несколько блоков в файл, начиная с файлового адреса, указанного полем «Номер записи при непосредственном доступе к файлу» в FCB. Читает данные из памяти, начиная с адреса DTA. Соответствующие поля FCB корректируются, чтобы указывать на следующую запись (первую за прочитанными).

DOS, функция 29h Разобрать имя файла

DS:SI – адрес исходной текстовой строки для разбора

ES:DI – адрес буфера для результирующего неоткрытого FCB (Таблица Б-2)

AL – битовые флаги, указывающие опции разбора (Таблица Б-5).

AL=00h, если результирующий FCB не содержит обобщенных символов

AL=01h, если результирующий FCB содержит обобщенные символы

AL=FFh, если неверно обозначение диска в имени файла

DS:SI – изменен – указывает на символ сразу вслед за именем файла

ES:DI – не изменен – указывает на неоткрытый FCB

Создает неоткрытый FCB из строки текста или параметра команды. Текст, начиная с DS:SI, анализируется как имя файла в формате D: FILENAME.EXT, и буфер по адресу ES:DI заполняется как соответственно форматированный FCB.

Таблица Б-5. Битовые флаги

DOS, функция 2Ah Получить системную дату

AL – день недели (0 – воскресенье, 1 – понедельник, … 6 – суббота), DOS 3.0+

CX – год (от 1980 до 2099)

DH – месяц (1 до 12)

DL – день (1 до 31)

Описание. Возвращает текущую дату, которая известна системе.

DOS 2.x не гарантирует возврата в AL значения дня.

DOS 1.0+ возвращает правильный день недели.

Версии до 2.1 имеют проблемы с переходом через дату.

DOS, функция 2Bh Установить системную дату

CX – год (от 1980 до 2099)

DH – месяц (от 1 до 12)

DL – день (от 1 до 31)

AL=00h, если дата корректна

AL=FFh, если дата некорректна и не изменена

Устанавливает системную дату DOS.

DOS, функция 2Ch Получить время DOS

CH – часы (от 0 до 23)

CL – минуты (от 0 до 59)

DH – секунды (от 0 до 59)

DL – сотые доли секунды (от 0 до 99)

Описание. Возвращает текущее время, которое известно системе.

Поскольку системные часы имеют частоту 18.2 Гц (интервал 55мс), DL имеет точность примерно 0.04 сек.

DOS, функция 2Dh Установить время DOS

CH – часы (от 0 до 23)

CL – минуты (от 0 до 59)

DH – секунды (от 0 до 59)

DL – сотые доли секунды (от 0 до 99)

AL=00h, если время корректно

AL=FFh, если время некорректно и не изменено

Устанавливает системное время DOS.

DOS, функция 2Eh Установить/сбросить переключатель верификации

AL=00h – отключить верификацию

AL=01h – включить верификацию

Описание. Задает, должна ли DOS верифицировать (считывать обратно) каждый сектор, записываемый на диск. Это замедляет операции записи на диск, но гарантирует максимальную надежность записи.

DOS, функция 2Fh Получить адрес текущей DTA

Выход: ES:BX – адрес начала текущей DTA

Описание. Возвращает адрес начала области ввода-вывода (DTA). Поскольку DTA глобальна для всех процессов, в рекурсивной процедуре (например, при проходе по дереву оглавления) может потребоваться сохранить адрес DTA, а впоследствии восстановить его посредством функции 1Ah.

Примечание. Эта функция изменяет сегментный регистр ES.

Версии: DOS 2.00 и выше DOS, функция 30h Получить номер версии DOS

AL – старший номер версии

AH – младший номер версии

BL:CX – 24-битный серийный номер (большинство версий не поддерживают этот параметр)

Описание. Возвращает в AX значение текущего номера версии DOS. Например, для DOS 3.20 в AL возвращается 03h, в AH – 14h.

Примечание. Если в AL возвращается 00h, можно предполагать, что работает DOS более ранней версии, чем DOS 2.0.

Версии: DOS 2.00 и выше. DOS, функция 31h Завершиться и остаться резидентным

DX – объем памяти, оставляемой резидентной (в параграфах)

Описание. Выходит в родительский процесс, сохраняя код выхода в AL. Код выхода можно получить через функцию 4Dh. DOS устанавливает начальное распределение памяти, как специфицировано в DX, и возвращает управление родительскому процессу, оставляя указанную память резидентной (число байт равно DX*16). Эта функция перекрывает функцию INT 27h, которая не возвращает код выхода и не способна установить резидентную программу, размер которой превышает 64 Кбайт.

Dos fn 32h: дать информацию dos о диске

Вообще, по ходу дела, для загрузочной дискеты ДОС нужно было, чтобы io.sys находился в первых секторах дискеты. как сейчас — не знаю, не знаю.

вот еще интересный вопрос. как наваять autoexec.bat и config.sys, имея только загрузочную дискету с драйвером mscdex и CD-ROM?

4. DeadPihto , 30.10.2003 20:24
Как вариант:
В config.sys
Device = %PATH%\»драйверCD-ROM.sys» /D:mscd001
В autoexec.bat
%PATH%\mscdex.exe /D:MSCD001

Где:
%PATH% =путь к файлу

5. Ильясла , 30.10.2003 20:45
vaio
>copy con yourfile.txt
bla-bla-bla
bla-bla-bla
[Ctrl+Z]

Добавление от 30.10.2003 21:09:

цитата: Lina Inverse:
To Андрон:
А в чем проблема достать sys.com?
.

готовлю серию дискет с дискавыми утилитами в которых хочу использовать dr-dos, а на тех дисках которые имеются есть только аналоги вышеперечисленныз трех файлов. Можно выкрутиться и через какой нибудь дубликатор но в данном случае преобладает скорее спортивный интерес

6. Андрон , 30.10.2003 21:03
7. SergeyO , 30.10.2003 21:14
Андрон
МС-ДОС (любой версии) прокатывает такой способ: если дискета была когда-то загрузочной, то можно просто скопировать IO.SYS, MSDOS.SYS, COMMAND.COM
8. Zim , 30.10.2003 21:53
Андрон
Проверь почту
9. Андрон , 31.10.2003 00:14
Спасибо, очень полезная дискетка, обязательно положу такую в комплект.

хочу сделать дискету с мултибутом которая бы давала возможность быстрой загрузки, даже без драйверов памяти. большинству дос утилит они не нужны, а время на загрузку отнимают.
Столкнулся с поблемой несовместимости MENUITEM между MS-DOS и DR-DOS — ищу документацию, пока безуспншно.

цитата (Андрон):
Помнится раньше работал такой способ:
форматируеш дискету, копируеш IO.SYS, затем MSDOS.SYS, и наконец COMMAND.COM

НО это было еще в дос 3.3, сейчас ничего не получается, может что забыл?

Ни в MS-DOS, ни в PC DOS такой способ не работал никогда. Ни до версий 3.3, ни после. А вот в DR DOS такая возможность была. Там не было привязки к сектору дискеты, на который передавалось управление из загрузчика. Достаточно было того, чтобы сами файлы присутствовали. И назывались они, между прочим, не IO.SYS и MSDOS.SYS, а так же, как и в PC DOS — IBMBIO.COM и IBMDOS.COM.

цитата (Андрон): Столкнулся с поблемой несовместимости MENUITEM между MS-DOS и DR-DOS — ищу документацию, пока безуспншно.

Несовместимость была даже между PC DOS и MS-DOS, не говоря уже о DR DOS (позднее — Novell DOS, ныне — Caldera Open DOS). В полной версии дистрибутива был хелп. Ищи дистрибутив.


Надо в архивах пятидюймовок порыться, у меня с 5-й версии по 7-ю все дистрибутивы были.

10. Старый Пе , 31.10.2003 01:19
11. yurfed , 31.10.2003 05:05
[b]Андрон[/b]
[q=Андрон]хочу сделать дискету с мултибутом которая бы давала возможность быстрой загрузки, даже без драйверов памяти. большинству дос утилит они не нужны, а время на загрузку отнимают. Столкнулся с поблемой несовместимости MENUITEM между MS-DOS и DR-DOS — ищу документацию, пока безуспншно.[/q]

Could someone please tell me how to do this in DR-DOS? Thanks.

A: Here is a sample CONFIG.SYS that will do the job. You can keep your autoexec.bat like in MS-DOS (you get an environment parameter CONFIG that you can use in auotexec.bat to specify the operations you want to do).

timeout=5
echo=1. Server
echo=2. DR-DOS
switch server, drdos
exit
:server
set config=server
return
:drdos
set config=drdos
Files=60
Buffers=20
Device=c:\CDROMDRV.SYS /D:CD001
return

Это отсюда http://www.drdos.net/faq/#p4_4_6

12. Akina , 31.10.2003 09:47
Андрон
Помнится раньше работал такой способ
он и сейчас работает — даже в ДОСе от МЕ. При условии что на дискете:

1) родной, от MS, generic boot sector;
2) файл IO.SYS (IBMBIO.COM) записан в первом элементе каталога (для ДОС 5.0 и младше).

format a:
copy io.sys a:\*.*
echo. > msdos.sys
copy command.com a:\*.*

делает нормальную загрузочную дискету.

vaio
для загрузочной дискеты ДОС нужно было, чтобы io.sys находился в первых секторах дискеты.
До ДОС 6.0 невключительно.

Андрон
без SYS.COM а /s есть не что иное как ктаткое к ней обращение
бред.

13. A_Bittner , 31.10.2003 10:04
И чего вы так мучаетесь?
http://www.bootdisk.com/bootdisk.htm

цитата (Akina):
Андрон
Помнится раньше работал такой способ
он и сейчас работает — даже в ДОСе от МЕ. При условии что на дискете:

1) родной, от MS, generic boot sector;
2) файл IO.SYS (IBMBIO.COM) записан в первом элементе каталога (для ДОС 5.0 и младше).

format a:
copy io.sys a:\*.*
echo. > msdos.sys
copy command.com a:\*.*

делает нормальную загрузочную дискету.

Не подходит такой способ, если нет загрузчика. Даже, если загрузчик раньше присутствовал, команда format a: этот загрузчик убьёт. И уж с этой дискеты загрузиться не получится. Рекомендую проверить, кстати. (При условии, что мы обсуждаем версии DOS от M$).

Другое дело, если отформатировать в том же DR DOS (Novell, Caldera). Там этот способ вполне может сработать — там другой формат загрузчика. Проверить пока не могу, но желание сделать это появилось.

14. Старый Пе , 01.11.2003 01:07
15. M-X , 02.11.2003 00:22
Андрон

Можно попробовать Norton Ghost.

16. 65536 , 02.11.2003 02:24
Старый Пе
Не подходит такой способ, если нет загрузчика. Даже, если загрузчик раньше присутствовал, команда format a: этот загрузчик убьёт. И уж с этой дискеты загрузиться не получится. Рекомендую проверить, кстати.
Странно, у меня этот способ работает, но только если форматировать format’ом от Win98, а если от WinXP, то не работает. Интересно, в чём между ними разница?

Добавление от 02.11.2003 02:32:

А-а, разобрался, в boot sector’е. Осталось его дизассемблировать, чтобы понять, в чём именно отличие.

17. Сергеич , 02.11.2003 11:47
Старый Пе

цитата:
Ни в MS-DOS, ни в PC DOS такой способ не работал никогда. Ни до версий 3.3, ни после.

Милейший, не порите чепухи. еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало

18. Старый Пе , 02.11.2003 13:00
Сергеич

Милейший, не порите чепухи. еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало

Ну-ну. Вот 65536 тоже возразить пытался, а провёл эксперимент — чуть ли извиняться не пришлось.

Ещё раз объясняю — всё дело в загрузчике.

Добавление от 02.11.2003 14:38:

Добавлю — у команды format есть ключ /b, который позволяет зарезервировать место для файлов BIO (*BIO.COM, IO.SYS) и DOS (*DOS.COM, MSDOS.SYS). В этом случае дискета становится загрузочной при простом копировании трёх недостающих файлов. Но «правильный» загрузчик в таком случае запишется только при выполнении команды sys a:.

Тонкий нюанс — в каждой ОС размер зарезервированного места чётко соответствует размерам файлов именно этой версии DOS, а загрузчик «знает» эти файлы по именам, поэтому адекватная работа этого метода гарантируется только в одной и той же версии DOS.

Сергеич
еще в 1989 году в техникуме именно так и делали загрузочную дискету

Спишем на некоторую забывчивость. Времени всё же немало прошло.

19. Сергеич , 02.11.2003 16:15
Старый Пе
Загрузчик от MS-DOS 3.0 точно пишет в BOOT то что надо для загрузки(по крайней мере для загрузки DOS 3.0). правда его сейчас не найти практически, а то можно было бы над кодом поспорить. насчет забывчивости — не было у нас (в смысле У МЕНЯ конкретно) полного ДОСа, приходилось загрузочную дискеты делать именно Форматом с последующим перекачиванием IO.SYS и MSDOS.SYS. кстати есть исходники от MS-DOS 6.22 можно посмотреть загрузочный сектор. так вот он сам ищет IO.SYS на дискете даже если тот раскидан как хрен знает что.

Насчет загрузчика естессно все от него и зависит, может быть современные ОС пишут на дискету в BOOT-сектор полный понос. не буду писать третий раз одно и то же про 3.0

Добавление от 02.11.2003 17:04:

Кстати сейчас не поленился проделать опыт. отформатировал дискету из-под XP, скопировал IO.SYS MSDOS.SYS COMMAND.COM загрузка не пошла. отформатировал из-под ME, сделал то же самое. как ни странно все загрузилось. да собственно иначе и быть не могло

PS Естессно MSDOS.SYS пришлось немного поправить на предмет того чтобы не грузиться с винта
PPS Кстати 65536 именно про это и написал, под 98 все получилось. за что извиняться то?

PPPS Кстати откройте Boot от дискеты, созданной XP. как он будет грузить DOS? Там даже намека на IO.SYS нет. а если создать загрузочный диск то бутсектор становится другой.

20. Старый Пе , 03.11.2003 03:46
Сергеич
Загрузчик от MS-DOS 3.0 точно пишет в BOOT то что надо для загрузки(по крайней мере для загрузки DOS 3.0). правда его сейчас не найти практически, а то можно было бы над кодом поспорить. насчет забывчивости — не было у нас (в смысле У МЕНЯ конкретно) полного ДОСа, приходилось загрузочную дискеты делать именно Форматом с последующим перекачиванием IO.SYS и MSDOS.SYS. кстати есть исходники от MS-DOS 6.22 можно посмотреть загрузочный сектор. так вот он сам ищет IO.SYS на дискете даже если тот раскидан как хрен знает что.

Готовьтесь съесть свою шляпу, уважаемый.

Проведены практические эксперименты со следующими версиями операционных систем:
MS-DOS 3.20
MS-DOS 3.30
MS-DOS 4.0
MS-DOS 4.01 rus
Compaq DOS 3.31
PC DOS 3.30
PC DOS 6.3
PC DOS 7
PTS-DOS 6.41

Исключение составили версии от IBM, Compaq и Phys-Tech-Soft, где соответствующие файлы создавались с соответствующими операционной системе именами.

Во всех случаях получен одинаковый результат — невозможность загрузки. Non-bootable disk. и т.д. Исключение составила дискета с PTS-DOS — она сразу передала управление на MBR жёсткого диска.

Повторяю для тех, кто не может понять своей ошибки — команда format в ранних версиях DOS (мы обсуждаем именно их, по крайней мере с этого ветка началась) без дополнительных (кроме имени дисковода) параметров полностью переписывала Boot Record дискеты таким кодом, который не позволял с этой дискеты загрузиться. Изменить Boot Record (и сделать дискету загрузочной) можно было только применив команду sys a: к этой дискете, но до начала записи на неё.

Исключение составляли версии DOS от Digital Research (DR-DOS, позднее ставшая Novell DOS, ещё позднее — Caldera DOS). О них — в следующий раз.

Дополнительно хочу заметить, что в операционных системах Windows 9X и т.д. файл MSDOS.SYS не является исполняемым файлом, как это было до версии 6.22 включительно. Поэтому команда echo. > msdos.sys также лишена смысла. Не было в DOS таких команд, т.е. никому бы не пришло в голову написать такую командную строку.

Кстати сейчас не поленился проделать опыт. отформатировал дискету из-под XP, скопировал IO.SYS MSDOS.SYS COMMAND.COM загрузка не пошла. отформатировал из-под ME, сделал то же самое. как ни странно все загрузилось. да собственно иначе и быть не могло

Это нужно принять, как подтверждение Ваших упражнений еще в 1989 году в техникуме ? Вы с Windows ME в техникуме упражнялись?

PS Естессно MSDOS.SYS пришлось немного поправить на предмет того чтобы не грузиться с винта

Это Вы о чём? В нашем примере мы его создаём командой echo. > msdos.sys, ни о какой правке речь не идёт. Да и что там править, пардон, в таком случае?

PPS Кстати 65536 именно про это и написал, под 98 все получилось. за что извиняться то?

За вот это, я думаю. => Милейший, не порите чепухи. еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало

В Windows 98SE такой номер проходит — только что проверил. Но Вы утверждаете, что делали подобный трюк в DOS 3.xx, что явная неправда.

PPPS Кстати откройте Boot от дискеты, созданной XP. как он будет грузить DOS? Там даже намека на IO.SYS нет. а если создать загрузочный диск то бутсектор становится другой.

Тут я даже комментировать не могу. Без обид, ладно?

21. Vladislav_A , 03.11.2003 09:01
Старый Пе
Во всех случаях исполнялись следующие действия, как предлагалось здесь:
format a:
copy io.sys a:\*.*

echo. > msdos.sys[b] — а вот этого для DOS 3.x-6.x делать не следовало, надо было [b]copy msdos.sys a:\
copy command.com a:\*.*
. Во всех случаях получен одинаковый результат — невозможность загрузки.

Результат не удевителен, тем более, что если не полениться и посмотреть 0 сектор загрузочной и не зарузочной дискеты с помощью DiskEdit то можно обнаружить немало различий.
22. Akina , 03.11.2003 09:20
Старый Пе
Не подходит такой способ, если нет загрузчика

Читать умеем? generic boot sector. или Вы не в курсе что это такое?

65536
у меня этот способ работает, но только если форматировать format’ом от Win98, а если от WinXP, то не работает. Интересно, в чём между ними разница?
Сергеич
Кстати сейчас не поленился проделать опыт. отформатировал дискету из-под XP, скопировал IO.SYS MSDOS.SYS COMMAND.COM загрузка не пошла. отформатировал из-под ME, сделал то же самое. как ни странно все загрузилось. да собственно иначе и быть не могло

ХР вообще не знает о существовании загрузочной дискеты. Потому у него пишется abstract boot sector.

Старый Пе
Тонкий нюанс — в каждой ОС размер зарезервированного места чётко соответствует размерам файлов именно этой версии DOS, а загрузчик «знает» эти файлы по именам, поэтому адекватная работа этого метода гарантируется только в одной и той же версии DOS.

Слушай, а ты попробуй такую штуку — форматни дискету с резервированием пространства под системные файлы, а потом скопируй туда файлы от другой версии и загрузись с дискеты. будешь (не)приятно удивлен.

Проведены практические эксперименты со следующими версиями операционных систем:

передача текста без понимания смысла? Впрочем Vladislav_A уже правильно ткнул носом.

23. Сергеич , 03.11.2003 11:40
Какой смысл доказывать сейчас с пеной у рта, что я делал 13-14 лет назад? насчет ME в те времена — ну да, именно с ней и пробовал, была стыренная из мелкософта pre-pre-pre-pre-pre-pre-alpha. всегда удивлялся людям, которые сами ничего не могут, но не потому, что не умеют, а потому, «что этого не может быть». Еще как может. не поленитесь прислать бут от дискеты дос 3.0 после обычного формата, самому к сожалению взять негде. там и поговорим. Третий раз повторяю, что так делал не только я, а еще как минимум десяток человек.
24. Старый Пе , 03.11.2003 11:59
Vladislav_A
а вот этого для DOS 3.x-6.x делать не следовало, надо было copy msdos.sys a:\

Это не мне объяснять надо, а специалистам, утверждающим, что еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало. Из моего сообщения явно следует, что я понимаю эту разницу.

К тому же, в нашем случае это никого не спасёт — дискета не грузится не по этой причине.

Akina
Читать умеем? generic boot sector. или Вы не в курсе что это такое?

По всей видимости, Вы готовы объяснить, как его получить, используя format a: в DOS 3.xx-6.xx. С доказательством того, что загрузка с такой дискеты без модификации boot sector-а осуществима.

передача текста без понимания смысла? Впрочем Vladislav_A уже правильно ткнул носом.

Может и ткнул. Только у ж точно не меня.

цитата:
приходилось загрузочную дискеты делать именно Форматом с последующим перекачиванием IO.SYS и MSDOS.SYS.

цитата: а вот этого для DOS 3.x-6.x делать не следовало, надо было copy msdos.sys a:\

Это не мне объяснять надо, а специалистам, утверждающим, что еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало. Из моего сообщения явно следует, что я понимаю эту разницу.

Как все запущено.

Загрузочный сектор, записываемый на дискету в ДОС 3.0-6.22, при команде Format a:, имеет следующую последовательность команд:


; We now begin to load the BIOS in.
; All we have to do is just read is multiply the BioStartClus
; by SecsPerClust to find the logical sector for the start
; of the BIOS file. When this value is added to the double
; word BiosHigh:BiosLow we get the absolute sector offset
; for the start of the file and then read the sectors
; contiguously IBM_LOAD_SIZE times. We here assume that
; IBMLOAD module is contiguous. Currently we estimate that
; IBMLOAD module will not be more than 3 sectors.
DoLoad:
mov AX,[BX].DIR_FIRST ; AX = BIOS starting cluster
dec AX ; Subtract first 2 reserved clusters
dec AX
mov BL,SecsPerClust ; BX = Sectors per cluster
xor BH,BH
mul BX ; DX:AX = first logical sector of bios

add AX,[BiosLow] ; Add absolute start sector
adc DX,[BiosHigh] ; DX:AX = Absolute bios sector offset

mov BX,BIO_OFFSET ;offset of ibmbio(IBMLOAD) to be loaded.
mov CX,IBM_LOAD_SIZE ;# of sectors to read.

Do_While:
push AX
push DX
push CX
call DoDiv ; DX:AX = sector number.
jc Load_Failure ; Adjust stack. Show error message
mov al, 1 ; Read 1 sector at a time.
; This is to handle a case of media
; when the first sector of IBMLOAD is the
; the last sector in a track.
call DoCall ; Read the sector.
pop CX
pop DX
pop AX
jc CkErr ; Read error?
add AX,1 ; Next sector number.
adc DX,0
add BX,BytesPerSector ; Adjust buffer address.
loop Do_While

; =========================================================================
; Main read-in loop.
; ES:BX points to area to read.
; Count is the number of sectors remaining.
; BIOS$ is the next logical sector number to read
;
; CurrentHead is the head for this next disk request
; CurTrk is the track for this next request
; CurSec is the beginning sector number for this request
;
; AX is the number of sectors that we may read.
;
; =========================================================================
;
; IBMINIT requires the following input conditions:
;
; DL = INT 13 drive number we booted from
; CH = media byte
; IBMBIO init routine should check if the boot record is the
; extended one by looking at the extended_boot_signature.
; If it is, then should us AX;BX for the starting data sector number.
; =========================================================================

DISKOK:
mov CH,MediaByte
mov DL,BootDrv
mov BX,[BiosLow] ; J.K.I1.Get bios sector in bx
mov AX,[BiosHigh] ; J.K.I1.
jmp FAR PTR Bios ;CRANK UP THE DOS

Доступно написано(между просим самими программерами Мелкософта) что код грузит три первых сектора из IO.SYS, и передает на них управление. Поэтому копирование системных файлов после формата и дает в итоге загрузочную дискету(так как проблема может быть только если эти первые три сектора идут не подряд, тогда загрузится некоторое количество лажи). Повторяю, это тот бут-сектор, который записывает ОБЫЧНАЯ команда FORMAT A:

Дальнейший спор видится бессмысленным. видимо каждый останется при своем мнении

25. Сергеич , 03.11.2003 12:21
26. mwz , 03.11.2003 15:12
Akina

И всю жизнь начиная по крайней мере с DOS-3 копирование в этой последовательности

copy io.sys a:\*.*
copy msdos.sys a:\*.*
а не echo.>a:\msdos.sys — это уже сказано
copy command.com a:\*.*

давало системную дискету DOS той версии, откуда эти 3 файла — если дискета форматировалась в DOS/Win9x как несистемная, а файлы брались от любой из DOS, даже не той, в которой форматировалось. А вот форматирование под NT-family этого не позволит, что тоже уже сказано.


цитата (mwz):
И всю жизнь начиная по крайней мере с DOS-3 копирование в этой последовательности

copy io.sys a:\*.*
copy msdos.sys a:\*.*
а не echo.>a:\msdos.sys — это уже сказано
copy command.com a:\*.*

давало системную дискету DOS той версии, откуда эти 3 файла — если дискета форматировалась в DOS/Win9x как несистемная, а файлы брались от любой из DOS, даже не той, в которой форматировалось. А вот форматирование под NT-family этого не позволит, что тоже уже сказано.

И где грибы такие забористые растут, даже интересно.

Неужели Вы никогда не забывали в дисководе дискету и при перезагрузке не получали строчку «Non-System disk or disk error. Replace and press any key when ready»? Не верю! (с) Станиславский.

И Вы тоже будете утверждать, что достаточно на такую дискету перенести простым копированием файлы IO.SYS, MSDOS.SYS и COMMAND.COM, чтобы она чудесным образом превратилась в загрузочную?

Давно такого бреда не читал. Всем срочно читать Фигурнова.

27. КоляН , 03.11.2003 17:37
28. Akina , 03.11.2003 17:46
КоляН
Так вот — если при загрузке с дискеты выдается сообщение Non-System disk or disk error. Replace and press any key when ready — то именно такая дискета после копирования на нее IO.SYS, MSDOS.SYS и COMMAND.COM станет загрузочной.

Дискета, которая НЕ станет загрузочной, напишет другое сообщение — Non-bootable disk. Insert bootable disk and strike Enter when ready (или очень близкое к этому).

Вышеуказанное верно для MS-DOS 3.30-6.22. PC-DOS, DRDOS и прочие — не знаю.

Для проверки того станет ли дискета загрузочной, можно глянуть содержимое ее бут-сектора. Если он забит «под завязку», и в конце есть стандартные имена загрузочных файлов — эта дискета станет загрузочной после копирования на нее системных файлов, если же бут-сектор наполовину состоит из нулей — нет.

29. Сергеич , 03.11.2003 17:50
Неужели Вы никогда не забывали в дисководе дискету и при перезагрузке не получали строчку «Non-System disk or disk error. Replace and press any key when ready»? Не верю! (с) Станиславский.

И Вы тоже будете утверждать, что достаточно на такую дискету перенести простым копированием файлы IO.SYS, MSDOS.SYS и COMMAND.COM, чтобы она чудесным образом превратилась в загрузочную?

Уважаемый, а вам и невдомек видимо, что эту надпись выводит сам бут-сектор при необнаружении на дискете IO.SYS и MSDOS.SYS? И если ему их дать, то все пойдет как по маслу(на любой дискете отформатированной ДОС 2.0-6.22 или 95-98-ме)?

30. traveller2002 , 03.11.2003 19:13
A_Bittner
Я думаю, приятно людям вспомнить, как они под Win 98 форматировали дискету, а потом копировали на нее системные файлы от MS DOS 3.3.
31. mwz , 04.11.2003 01:38
КоляН
Фигурнова я читал ещё в 80-х, и не скажу, что это лучшее из книг по компьютерной тематике: Богумирский куда точнее и понятнее писал.

А таже Ливингстон, с его «Секретами. » по различным операционкам.

Впервые сам применил этот метод где-то в 80-х, на DOS то ли 3.3, то ли 4.01: не было на винчестере файлов SYS.COM и FORMAT.COM, да и прочих тоже (машина была обрезана по максимуму), а загрузочную дискету надо было сделать срочно.

Если интересует — могу прислать образы дискеты сразу после форматирования (час назад) под DOS-6.22 как несистемной, и её же — после последующего копирования трёх упомянутых файлов от той же DOS-6.22 (80 кил архив).

Некоторые уточнения по моим и другим высказываниям на эту тему:
(1) В DOS-6.22 порядок и месторасположение этих файлов в записи корневого каталога также существенны. Изменять порядок стало можно начиная с Win95.
(2) Если при DOS-форматировании была введена метка тома — до её удаления системной дискету методом прямого копирования не сделать: метка тома займёт первое место в записи корневого каталога, т.е. то, которое должен занимать io.sys.
(3) Файлы от Win9х не пойдут на дискете, форматированной в DOS-3. 6.22, и наоборот.

Ну и, кроме всего прочего, я не считаю эту тему актуальной. Таковой она была бы лет 10 назад. Так что от последующих экспериментов меня увольте.

32. Старый Пе , 04.11.2003 04:54
Akina
Сергеич

Признаю свою неправоту. Привёл условия «эксперимента» к реальным (MSDOS.SYS) и всё заработало.

Но! Если разбираться по-хорошему, то ошибок в этой ветке достаточно, и не только у меня. И про необязательность записи файла IO.SYS первым, и про полную совместимость (и обратную применимость) загрузчика/системных файлов от старых версий DOS и новых (aka 7.XX, Win9X).

Зато архив пятидюймовых дискет разобрал. Много чего интересного нашёл.

Одного вот только не понял.

цитата (Akina): передача текста без понимания смысла? Впрочем Vladislav_A уже правильно ткнул носом.

Кто и кого ткнул носом? И в каком посте?

33. Akina , 04.11.2003 08:41
Старый Пе
Одного вот только не понял.
Насчет того что для версий 6.22 и младше MSDOS.SYS не создается через echo, а копируется (в старых версиях это был исполняемый файл, а не файл конфигурации). Очевидно же ж.
34. Сергеич , 04.11.2003 12:46
Ладно. разобрались и гут. теперь можно и
35. КоляН , 04.11.2003 13:31
mwz
Если интересует — могу прислать образы дискеты сразу после форматирования (час назад) под DOS-6.22 как несистемной, и её же — после последующего копирования трёх упомянутых файлов от той же DOS-6.22 (80 кил архив).

Хм-м-м. Интересует. И от 3.30, если есть.

Добавление от 04.11.2003 14:06:

Можно образы не высылать.

Вообще классно — условия эксперимента меняются по ходу эксперимента. То вы создаёте системные файлы «с нуля» в командной строке, то копируете. Разумеется, в виндовых DOS-ах (о как!) функции обоих системных файлов выполняет один IO.SYS, а раньше эти функции были разделены. Так что файл-пустышка будет работать только на дискете, созданной в Windows 95 (98, Me).

36. mwz , 04.11.2003 21:03
Так что файл-пустышка будет работать только на дискете, созданной в Windows 95 (98, Me).
Тут я согласен абсолютно — и отметил это для себя ещё при чтении соответствующих сообщений.

И от 3.30, если есть.
Я уже сказал, что тема некритична, и что от последующих экспериментов меня увольте. Да и искать DOS-3.3 желания нет — у меня не сохранилось ничего до 6.22.

Так как с уже имеющимися образами DOS-6.22, высылать или нет?

37. КоляН , 04.11.2003 21:11
mwz
Так как с уже имеющимися образами DOS-6.22, высылать или нет?

Да всё уже, проехали.

цитата (Akina):
Старый Пе
Одного вот только не понял.
Насчет того что для версий 6.22 и младше MSDOS.SYS не создается через echo, а копируется (в старых версиях это был исполняемый файл, а не файл конфигурации). Очевидно же ж.

А о чём тогда я здесь (http://forum.ixbt.com/topic.cgi? >

38. Старый Пе , 05.11.2003 01:16

цитата (Старый Пе): Сергеич
PPS Кстати 65536 именно про это и написал, под 98 все получилось. за что извиняться то?

За вот это, я думаю. => Милейший, не порите чепухи. еще в 1989 году в техникуме именно так и делали загрузочную дискету. версии были MS-DOS 3.0-3.3. Как ни странно все работало

Операционная система MS-DOS

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

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

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

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

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

39. 65536 , 14.11.2003 03:57
На входе: AH = 0Eh
DL = Номер дисковода (0 — А:, 1 — В:, и т.д.)
На выходе: AL = Общее количество дисководов в системе. Эта величина соответствует параметру LASTDRIVE файла CONFIG.SYS.

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

На входе: AH = 19h
На выходе: AL = Номер текущего дисковода (0 — А:, 1 — В:, и т.д.).

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

На входе: AH = 3Bh
DL = Номер дисковода (0 — текущий, 1 — А:, 2 — В:, и т.д.)
DS:DX = Адрес буфера, содержащего путь каталога, который должен стать текущим.
На выходе: AX = Код ошибки, если CY установлен в 1.

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

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

На входе: AH = 47h
DL = Номер дисковода ( — текущий, 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 = Количество байтов в одном секторе.

Дополнительно эта функция возвращает информацию об общем количестве кластеров на диске, размере кластера в секторах и размере сектора в байтах. Для версий MS-DOS, более ранних, чем 2.0, регистровая пара DS:BX указывала на FAT, считанный в память. Более поздние версии операционной системы могут содержать по этому адресу только часть таблицы размещения файлов.

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

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

На входе: AH = 36h
DL = Номер дисковода ( — текущий, 1 — А:, 2 — В:, и т.д.)
На выходе: AX = Количество секторов в кластере; 0FFFFh, если был задан неправильный номер дисковода;
BX = Количество свободных кластеров на диске.
CX = Количество байтов в одном секторе.
DX = Общее количество кластеров на диске.

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

При обсуждении векторной таблицы связи мы рассказывали о блоках управления устройствами DDCB. Поле dev_cb векторной таблицы связи содержит FAR-адрес цепочки этих блоков.

Приведем еще раз формат блока DDCB. Напомним, что он изменяется в зависимости от версии DOS. Для версий 2.х и 3.х блок DDCB имеет следующий формат:

(0) 1 drv_num номер устройства ( соответствует устройству А:, 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) 2 root_sec номер первого сектора корневого каталога
(+18) 4 drv_addr FAR-адрес заголовка драйвера, обслуживающего данное устройство
(+22) 1 media байт описания среды носителя данных
(+23) 1 acc_flag флаг доступа, означает, что к устройству был доступ
(+24) 4 next адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF
————— только для DOS 2.x —————
(+28) 2 dir_clu номер начального кластера текущего каталога (0 для корневого каталога)
(+30) 64 dir_path строка в формате ASCIIZ, содержащая путь к текущему каталогу
————— DOS 3.х —————————-
(+28) 2 reserv1 зарезервировано, обычно равно 0
(+30) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Формат блока DDCB для DOS версии 4.х:

(0) 1 drv_num номер устройства ( соответствует устройству А:, 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 флаг доступа, означает, что к устройству был доступ
(+25) 4 next адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF
(+29) 2 reserv2 зарезервироано
(+31) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Файл sysp.h содержит определение типа DDCB для MS-DOS версии 4.х:

При описании векторной таблицы связи мы приводили примеры использования блоков DDCB. Для получения адреса блока DDCB конкретного дисковода можно воспользоваться недокументированной функцией 32h. Она имеет следующий формат вызова:

На входе: AH = 32h
DL = Номер дисковода ( — текущий, 1 — А:, 2 — В:, и т.д.)
На выходе: AL = 0, если был задан правильный номер дисковода;
0FFh, если был задан неправильный номер дисковода;
DS:BX = Адрес блока DDCB

Для получения адреса блока DDCB текущего диска можно воспользоваться недокументированной функцией 1Fh, которая имеет формат, аналогичный функции 32h, за исключением того, что не надо задавать номер дисковода в регистре DL.

Какая еще полезная информация может быть получена при использовании функций MS-DOS?

С помощью функции 33h программа может проверить или установить флаг Ctrl-Break и узнать номер диска, с которого выполнялась загрузка операционной системы:

На входе: AH = 33h
AL = Код подфункции:
— Проверить текущее состояние флага Ctrl-Break;
1 — Установить флаг Ctrl-Break;
5 — Определить номер диска, который был использован для загрузки операционной системы.
DL = Значение устанавливаемого флага Ctrl-Break для подфункции 1 (0 — OFF, 1 — ON).
На выходе: DL = Текущее состояние флага Ctrl-Break для подфункции 0;
Номер диска, использованного для загрузки операционной системы для подфункции 5 (1 — А:, 2 — В:, и т.д.).

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

Состояние флага Ctrl-Break влияет на возможность прервать выполнение программы нажатием комбинации клавиш Ctrl-Break или Ctrl-C. Если флаг находится в состоянии OFF, DOS проверяет эту комбинацию клавиш только при вызове функций стандартного ввода/вывода на консоль, принтер и последовательный порт. Если флаг установлен в состояние ON, комбинация клавиш проверяется и при вызове других функций MS-DOS. Если операционная система зафиксировала нажатие указанной комбинации клавиш, она выполняет прерывание INT 23h, которое завершает работу текущей программы.

Функция 2Fh возвращает в регистровой паре ES:BX адрес текущей области DTA (Disk Transfer Area), которая используется при поиске файлов в каталогах.

Функция 54h позволяет программе узнать текущее состояние флага проверки записывающейся на диск информации. В регистре AL эта функция возвращает текущее состояние флага. Если содержимое регистра равно 1, операционная система после записи сектора считывает его для проверки. Разумеется, такая проверка снижает скорость работы программы. Если после вызова функции регистр AL содержит 0, проверка записи не выполняется.

Для установки флага проверки записи можно использовать функцию 2Eh. Перед вызовом функции в регистр AL необходимо занести новое значение флага проверки: — проверка не нужна; 1 — должна выполняться проверка записанной информации.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат несколько функций, облегчающих получение справочной информации о состоянии дисковой подсистемы.

Функция _dos_getdiskfree() использует функцию 36h для получения информации о диске. Файл dos.h содержит описание этой функции:

Параметр drive задает номер используемого дисковода: — текущий, 1 — А:, и т.д.

Информация возвращается в структуре diskfree_t, которая определена в файле dos.h:

В этой структуре:

unsigned total_clusters общее количество кластеров на диске;
unsigned avail_clusters количество свободных кластеров;
unsigned sectors_per_cluster количество секторов, занимаемых кластером;
unsigned bytes_per_sector размер сектора в байтах.

Для получения номера текущего диска и для установки номера текущего диска можно использовать, соответственно, функции _dos_getdrive() и _dos_setdrive().

Функция _dos_getdrive() имеет формат:

Эта функция пользуется функцией 19h для получения номера текущего диска, который записывается по адресу, задаваемому параметром. Значение 1 соответствует диску А:, 2 — В:, и т.д.

Функция _dos_setdrive() предназначена для установки текущего диска и может быть использована для определения общего числа дисков в системе:

Параметр drive опеределяет текущий диск (1 — А:, и_т.д.), по адресу, задаваемому вторым параметром, функция записывает общее количество логических дисков, установленных в системе. Функция _dos_setdrive() использует функцию 0Eh прерывания INT 21h.

Для иллюстрации способов использования функций _dos_getdrive(), _dos_setdrive(), _dos_getdiskfree() мы составили следующую программу:

Илон Маск рекомендует:  Что такое код pg_delete
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL