Ru/api/kernel: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
Line 350: Line 350:
== Функция 58 - работа с файловой системой. ==
== Функция 58 - работа с файловой системой. ==


Параметры:
Описание функции перенесено в отдельную статью: [[SysFn58/ru | Функция 58]]
  * eax = 58
  * ebx = указатель на информационную структуру
Возвращаемое значение:
  * eax = 0 - успешно; иначе код ошибки файловой системы
  * в зависимости от подфункции может возвращаться значение и
    в других регистрах
Общий формат информационной структуры:
  * +0: dword: номер подфункции
  * +4: dword: номер блока
  * +8: dword: размер
  * +12 = +0xC: dword: указатель на данные
  * +16 = +0x10: dword: указатель на память для работы системы
    (4096 байт)
  * +20 = +0x14: n db: ASCIIZ-строка с именем файла
Уточнения - в документации на соответствующую подфункцию.
Имя файла нечувствительно к регистру латинских букв,
русские буквы должны быть заглавными.
Формат имени файла:
/base/number/dir1/dir2/.../dirn/file,
где /base/number идентифицирует устройство, на котором ищется файл:
одно из
  * /RD/1 = /RAMDISK/1 для доступа к рамдиску
  * /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу,
    /FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода
  * /HD/x = /HARDDISK/x - устаревший вариант доступа к жёсткому диску
    (в этом случае база определяется подфункцией 7 функции 21),
    x - номер раздела (считая с 1)
  * /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно
    к устройствам IDE0 (Primary Master), IDE1 (Primary Slave),
    IDE2 (Secondary Master), IDE3 (Secondary Slave);
    x - номер раздела на выбранном винчестере, изменяется от 1 до 255
    (на каждом из винчестеров нумерация начинается с 1)
Замечания:
  * В первых двух случаях допускается использование FIRST вместо 1,
    SECOND вместо 2, но использовать эту возможность
    не рекомендуется для удобства перехода на будущие расширения.
  * Накладывается ограничение n<=39.
  * Имена папок и файла dir1,...,dirn,file должны быть в формате 8.3:
    имя не более 8 символов, точка, расширение не более 3 символов.
    Хвостовые пробелы игнорируются. Других пробелов быть не должно.
    Если имя занимает ровно 8 символов, точку можно опустить
    (хотя пользоваться этим не рекомендуется для удобства перехода
    на будущие расширения).
  * Функция не поддерживает папок на рамдиске.
Примеры:
  * '/RAMDISK/FIRST/KERNEL.ASM',0
    '/rd/1/kernel.asm',0
  * '/HD0/1/kernel.asm',0
  * '/hd0/1/menuet/pics/tanzania.bmp',0
Доступные подфункции:
  * подфункция 0 - чтение файла/папки
  * подфункция 8 - LBA-чтение с устройства
  * подфункция 15 - получение информации о файловой системе
 
 
=== Подфункция 0 - прочитать файл/папку. ===
 
Параметры:
  * eax = 58
  * ebx = указатель на информационную структуру
Формат информационной структуры:
  * +0: dword: 0 = номер подфункции
  * +4: dword: номер блока для чтения (считая с 0)
  * +8: dword: число блоков для чтения
  * +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
  * +16 = +0x10: dword: указатель на буфер для работы системы
    (4096 байт)
  * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в
    общем описании
Возвращаемое значение:
  * eax = 0 - успешно, иначе код ошибки файловой системы
  * ebx = размер файла (в байтах) или
    -1=0xffffffff, если файл не найден
Замечания:
  * Размер блока - 512 байт.
  * Эта функция устарела, для чтения файлов используйте подфункцию 0
    функции 70, для чтения папок - подфункцию 1 функции 70.
  * Функция позволяет читать содержимое папки. Из файловых систем
    поддерживается только FAT. Формат FAT-папки описан в любой
    документации по FAT.
  * Размер папки определяется по размеру цепочки кластеров в FAT.
  * Если файл кончился раньше, чем был прочитан последний запрошенный
    блок, то функция прочитает, сколько сможет, после чего вернёт
    eax=6 (EOF).
  * Функция позволяет читать корневые папки /rd/1,/fd/x,/hd[n]/x, но
    в первых двух случаях текущая реализация не следует
    установленным правилам:
    для /rd/1:
    * если указано 0 блоков для чтения, считается,
      что запрашивается 1;
    * если запрашивается больше 14 блоков или начальный блок
      не меньше 14-го, то возвращается eax=5 (not found) и ebx=-1;
    * размер корневого каталога рамдиска = 14 блоков,
      0x1C00=7168 байт; но возвращается ebx=0
      (за исключением случая предыдущего пункта);
    * как ни странно, можно прочитать 14-й блок (там, вообще говоря,
      мусор - напоминаю, счёт ведётся с 0);
    * если был запрошен хотя бы один блок с номером, не меньшим 14,
      то возвращается eax=6(EOF); иначе eax=0.
    Для /fd/x:
    * если начальный блок не меньше 14-го, то возвращается
      eax=5 (not found) и ebx=0;
    * кстати говоря, формат FAT12 допускает дискеты с размером
      корневого каталога меньше или больше 14 блоков;
    * проверки длины не делается;
    * если удалось прочитать данные с дискеты, возвращается
      eax=0,ebx=0; в противном случае eax=10 (access denied), ebx=-1.
  * Функция обрабатывает чтение специальных папок /,/rd,/fd,/hd[n];
    но результат не соответствует ожидаемому
    (по работе с обычными файлами/папками), не следует установленным
    правилам, может измениться в следующих версиях ядра и потому
    не описывается. Для получения информации об оборудовании
    используйте подфункцию 11 функции 18 или
    читайте соответствующие папки подфункцией 1 функции 70.
 
 
=== Подфункция 8 - LBA-чтение с устройства. ===
 
Параметры:
  * eax = 58 - номер функции
  * ebx = указатель на информационную структуру
Формат информационной структуры:
  * +0: dword: 8 = номер подфункции
  * +4: dword: номер блока для чтения (считая с 0)
  * +8: dword: игнорируется (устанавливайте в 1)
  * +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
    (512 байт)
  * +16 = +0x10: dword: указатель на буфер для работы системы
    (4096 байт)
  * +20 = +0x14: ASCIIZ-имя устройства: нечувствительно к регистру,
    одно из /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
    1<=n<=4 - номер устройства: 1=IDE0, ..., 4=IDE3.
    Вместо цифр допускается, хотя и не рекомендуется для удобства
    перехода на будущие расширения,
    использование 'first','second','third','fourth'.
Возвращаемое значение:
  * если указано имя устройства /hd/xxx, где xxx не находится
    в списке выше:
    * eax = ebx = 1
  * если указано неправильное имя устройства
    (за исключением предыдущего случая):
    * eax = 5
    * ebx не меняется
  * если LBA-доступ запрещён подфункцией 11 функции 21:
    * eax = 2
    * ebx разрушается
  * для рамдиска: попытка чтения блока за пределами рамдиска
    (18*2*80 блоков) приводит к
    * eax = 3
    * ebx = 0
  * при успешном чтении:
    * eax = ebx = 0
Замечания:
  * Размер блока - 512 байт; читается один блок.
  * Не следует полагаться на возвращаемое значение,
    оно может измениться в следующих версиях.
  * Требуется, чтобы был разрешён LBA-доступ к устройствам
    подфункцией 11 функции 21. Узнать это можно вызовом
    подфункцией 11 функции 26.
  * LBA-чтение дискеты не поддерживается.
  * Функция считывает данные физического жёсткого диска;
    если по каким-то причинам нужны данные конкретного раздела,
    придётся определять начальный сектор этого раздела
    (либо напрямую через MBR, либо из расширенной структуры,
    возвращаемой той же подфункцией 11 функции 18).
  * Функция не проверяет код ошибки жёсткого диска, так что запрос
    несуществующего сектора всё равно что-то прочитает
    (вероятнее всего, нули, но это определяется устройством) и
    это будет считаться успехом (eax=0).
 
 
= Функция 58, подфункция 15 - получить информацию о файловой системе.
 
Параметры:
  * eax = 58 - номер функции
  * ebx = указатель на информационную структуру
Формат информационной структуры:
  * +0: dword: 15 = номер подфункции
  * +4: dword: игнорируется
  * +8: dword: игнорируется
  * +12 = +0xC: dword: игнорируется
  * +16 = +0x10: dword: игнорируется
  * +20 = +0x14: (проверяется только второй символ, сразу после слэша)
    /rd=/RAMDISK или /hd=/HARDDISK
Возвращаемое значение:
  * если второй символ не принадлежит множеству {'r','R','h','H'}:
    * eax = 3
    * ebx = ecx = dword [fileinfo] = 0
  * для рамдиска:
    * eax = 0 (успех)
    * ebx = общее число кластеров = 2847
    * ecx = число свободных кластеров
    * dword [fileinfo] = размер кластера = 512
  * для жёсткого диска: база и раздел определяются подфункциями 7 и 8
    функции 21:
    * eax = 0 (успех)
    * ebx = общее число кластеров
    * ecx = число свободных кластеров
    * dword [fileinfo] = размер кластера (в байтах)
Замечания:
  * Не удивляйтесь странному расположению 4-го возвращаемого
    параметра - когда писался этот код, при системных вызовах
    приложению возвращались только регистры eax,ebx,ecx (из
    pushad-структуры, передающейся как аргумент системной функции).