Команды для создание своих сборок windows 7. Как с помощью программы NTLite создать собственную сборку Windows. Компоненты, функции и службы Windows

FAT (англ. File Allocation Table - «таблица размещения файлов»)- классическая архитектура файловой системы, которая из-за своей простоты всё ещё широко используется для флеш-накопителей. Используется в дискетах, и некоторых других носителях информации. Ранее использовалась и на жестких дисках.

Файловая система была разработана Биллом Гейтсом и Марком Мак Дональдом в 1977 году и первоначально использовалась в операционной системе 86-DOS. В дальнейшем 86-DOS была приобретена Microsoft и стала основой для ОС MS-DOS 1.0, выпущенной в августе 1981 года. FAT была предназначена для работы с гибкими дисками размером менее 1 Мб, и вначале не предусматривала поддержки жестких дисков.

Сейчас существует четыре версии FAT - FAT8, FAT12 , FAT16 и FAT32 . Они отличаются разрядностью записей в дисковой структуре, то есть количеством бит, отведённых для хранения номера кластера . FAT12 применяется в основном для дискет, FAT16 - для дисков малого объёма, FAT32- для жестких дисков. На основе FAT была разработана новая файловая система exFAT (extended FAT), используемая преимущественно для флеш-накопителей.

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

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

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

Организация файловой системы fat

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

A- дорожка

C- кластер

Рисунок 1- Структура диска

Дорожки - это концентрические окружности, покрывающие поверхность диска. Ближайшей к краю диска дорожке присвоен номер 0, следующей за ней - 1 и т.д. Если дискета двусторонняя, то пронумерованы обе ее стороны. Номер первой стороны - 0, номер второй - 1.

Каждая дорожка разбивается на участки, называемые секторами . Секторам также присваиваются номера. Первому сектору на дорожке присваивается номер 1, второму - 2 и т.д.

Жесткий диск состоит из одной или нескольких круглых пластин. Для хранения информации используются обе поверхности пластины. Каждая поверхность разбивается на дорожки, дорожки, в свою очередь, - на сектора. Дорожки одинакового радиуса составляют цилиндр . Таким образом, все нулевые дорожки составляют цилиндр с номером ноль, дорожки с номером 1 - цилиндр с номером 1 и т.д.

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

Эту файловую систему используют такие операционные системы, как Windows NT/2000/XP. При установке NTFS, диск разделяется на две неравные части: первая отводиться под MFT (Master File Table - общая таблица файлов), называется MFT - зоной и занимает порядка 12% от общего размера диска, вторую часть занимают собственно Ваши данные. Есть еще и третья зона, но о ней позже. Что за зверь этот MFT? Это основа NTFS. Он лежит, как было сказано ранее, в MFT - зоне т. е. в начале диска. Каждая запись в MFT соответствует какому-либо файлу и занимает около 1 Kb. По своей сути это каталог всех файлов находящихся на диске. Надо заметить, что любой элемент данных в NTFS рассматривается как файл, даже MFT. Первые 16 файлов (метафайлы) в MFT - зоне являются особой кастой. В них содержится служебная информация, они имеют фиксированное положение и они недоступны даже операционной системе. Кстати, первым из этих 16 является сам MFT - файл. Существует копия первых трех записей. Помните, я говорил о третьей зоне, так вот там она и лежит и своим положением, если можно так выразиться, делит диск пополам. Зачем это сделано? Да для надежности, в случае утери информации в MFT - файле, всегда можно восстановить информацию, а там уже дело техники, как говориться. Все остальные файлы в MFT - зоне могут располагаться произвольно. Надо заметить, что в MFT - зоне теоретически кроме служебных файлов ничего не находиться. Но бывают случаи, когда места на той части диска, что отведена для пользователя не остается:-(и тогда MFT - зона уменьшается. Соответственно появляется место во второй половине диска для записи данных. Когда же в этой зоне освобождается достаточное количество свободного места, MFT - зона опять расширяется. И вот тут то появляется проблема. В MFT - зону попадают обычные файлы и она начинает фрагментироваться. Это не смертельно конечно, но и приятного тут мало. Но вернемся к нашим баранам, то бишь метафайлам. Каждый из них отвечает за какую-либо область работы. Начинаются они с символа имени $ (тем, кто занимается программированием значок известен). Приведу пример некоторых из них:

  • MFT - не что иное как сам MFT
  • MFTmirr - та самая копия, что по серединке диска
  • LogFile - это файл журналирования
  • Boot - как видно из названия, его величество загрузочный сектор
  • Bitmap - карта свободного места раздела

Ну и так далее. Информация о метафайлах находиться в MFT - файле. Сложно? Есть такое дело. Но вся эта фигня придумана для увеличения надежности NTFS и себя оправдывает. Едем дальше. NTFS практически не имеет ограничения на размеры диска (во всяком случае при нынешних технологиях производства жестких дисков). Размер кластера может варьироваться от 512 b до 64 Kb, хотя обычный его размер равен 4 Kb.

Поговорим теперь о каталоге. Это метофайл с обозначением $. . Он разделен на части в каждой из которых содержится имя файла, его атрибуты и ссылка на MFT - файл. А там уже есть вся остальная информация. Каталог представляет собой бинарное дерево. Попробуем разобраться, что это за фигня такая. В каталоге информация о данных на диске расположена таким образом, что при поиске какого-либо файла каталог разбивался на две части и ответ заключался в том, в какой именно части находиться искомое. Затем та же самая операция повторяется в выбранной половине. И так до тех пор, пока не будет найден нужный файл.

А теперь о файлах. Их как таковых нет. Нормально, да! Есть так называемые стримы, или говоря нормальным русским языком - потоки. То есть, любая единица информации представляет собой несколько потоков. Один поток - это сами данные, он является основным. Другие потоки - атрибуты файла. К любому файлу можно прикрепить любой другой файл. Проще говоря, к потокам одних данных можно прикрепить совершенно новый поток и записать туда новые данные. Вот только информация по объему файла берется по объему основного потока. Пустые или малоразмерные файлы на диске отображены только в метафайлах. Сделано это в целях экономии дискового пространства. Вообще надо отметить, что понятие файл намного глубже и шире и все свойства описать довольно сложно. Отмечу, что максимальная длина имени файла может достигать 255 символов.

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

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

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

И наконец в NTFS есть еще две такие функции, как Symbolic Links - возможность создания виртуальных каталогов, и Hard Links - поддержка нескольких имен для одного и того же файла.Вот пожалуй что и все.

На данный момент времени эта файловая система является самой распространенной, хотя и сдает постепенно свои позиции после выхода Windows XP. Поддерживают FAT 32 все операционные системы семейства Windows начиная с Windows 95 OSR2. Итак, FAT 32 (File Allocation Table) - это электронная таблица размещения файлов. Находиться она практически в самом начале диска. Структура диска FAT:

    1. загрузочные секторы главного и дополнительного разделов;
    2. загрузочный сектор логического диска;
    3. корневой каталог;
    4. область данных;
    5. цилиндр для выполнения диагностических операций чтения/записи;

Основное преимущество FAT 32 перед FAT 16 заключается в том, что вместо 16 разрядных записей используются 32х разрядные. Это в свою очередь увеличивает количество кластеров в разделе до 268 435 456 (в FAT - 65 536). При использовании FAT 32 размер тома равен 2 Tb, а размер одного файла может достигать 4 Gb. Заметное отличие FAT 32 от предшествующих таблиц заключается в том, что корневой каталог не занимает фиксированного места на диске и может иметь любой размер.

Размер кластера при использовании FAT 32 в разделе размером 2 Gb с 5 000 файлами равен 4 Kb (в FAT 16 - 32 Kb), в таблице будет использоваться до 524 288 записей. При этом сама таблица будет весить порядка 2 Мb.

Сравнение NTFS и FAT 32.

Ну что, займемся неблагодарным делом - сравнением двух файловых систем.

Достоинства:

    1. Быстрая скорость доступа к файлам малого размера;
    2. Размер дискового пространства на сегодняшний день практически не ограничен;
    3. Фрагментация файлов не влияет на саму файловую систему;
    4. Высокая надежность сохранения данных и собственно самой файловой структуры;
    5. Высокая производительность при работе с файлами большого размера;

Недостатки:

    1. Более высокие требования к объему оперативной памяти по сравнению с FAT 32;
    2. Работа с каталогами средних размеров затруднена из-за их фрагментации;
    3. Более низкая скорость работы по сравнению с FAT 32

Достоинства:

    1. Высокая скорость работы;
    2. Низкое требование к объему оперативной памяти;
    3. Эффективная работа с файлами средних и малых размеров;
    4. Более низкий износ дисков, вследствие меньшего количества передвижений головок чтения/записи.

Недостатки:

    1. Низкая защита от сбоев системы;
    2. Не эффективная работа с файлами больших размеров;
    3. Ограничение по максимальному объему раздела и файла;
    4. Снижение быстродействия при фрагментации;
    5. Снижение быстродействия при работе с каталогами, содержащими большое количество файлов;

Итак, некоторые соображения. Обе файловые системы хранят данные в кластерах минимальный размер которого равен 512 b. Как правило обычный размер кластера равен 4 Kb. На этом сходства пожалуй и заканчиваются. Кое-что о фрагментации: скорость работы NTFS резко снижается при заполнении диска на 80 - 90 %. Это связано с фрагментацией служебных и рабочих файлов. Чем больше Вы работаете с таким загруженным диском, тем сильнее фрагментация и тем ниже производительность. В FAT 32 фрагментация рабочей области диска происходит и на более ранних этапах. Дело тут зависит от того, насколько часто Вы записываете/стираете данные. Как и в NTFS, фрагментация сильно снижает производительность. Теперь об оперативной памяти. Объем самой электронной таблицы FAT 32 может занимать в ОЗУ порядка нескольких мегабайт. Но на помощь приходит кэширование. Что записывается в кэш:

    1. Наиболее используемые каталоги;
    2. Данные о всех используемых в данный момент времени файлах;
    3. Данные о свободном пространстве диска;

А что же NTFS? Кэшированию трудно поддаются каталоги больших размеров, а они могут достигать размеров нескольких десятков мегабайт. Плюс MFT, плюс информация о свободном месте на диске. Хотя надо заметить, что NTFS все же довольно экономно расходует ресурсы оперативной памяти. В наличии удачная система хранения данных, в MFT каждая запись примерно равна 1 Kb. Но все же требования к объему ОЗУ выше, чем для FAT 32. Короче, если Ваша память меньше или равна 64 Mb, то эффективнее с точки зрения скорости окажется FAT 32. Если больше - разница в скорости будет маленькая, а зачастую вообще никакой. Теперь о самом жестком диске. Для использования NTFS желательно наличие Bus Mastering. Что это? Это особый режим работы драйвера и контроллера. При использовании BM обмен происходит без участия процессора. Отсутствие ВМ скажется на производительности системы. Кроме этого, вследствие использования более сложной файловой системы количество движений головок чтения/записи возрастает, что так же влияет на скорость. Наличие дискового кэша одинаково положительно сказывается, как на NTFS, так и на FAT 32.

На сегодня выбор файловой системы при форматировании носителя становится актуальным. Допустим, Вы хотите отформатировать жесткий диск или флэшку, при этом есть выбор: отформатировать в такие файловые системы как NTFS , FAT32 , FAT , FAT16 , exFAT . Существует еще , но таковой, по сути, не является, а обозначает наличие проблем с диском.

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

Сейчас мы поговорим о том, в чем отличие FAT32 от NTFS.

Отличие FAT32 от NTFS

FAT32 – файловая система создана на основе FAT16. Она является наиболее старой и не безопасной. Также, технология FAT использовалась еще в Windows 95 и 98. Если Ваш носитель отформатирован под данную файловую систему, то файлы, находящиеся на носителе видны любому пользователю, имеющему доступ к компьютеру. Минус файловой системы в том, что она имеет ограничение на размер. Создать раздел более 32 Гб невозможно. Расшифровка файловой системы выглядит так: File Allocation Table.

NTFS – эта файловая система наиболее предпочтительна и имеет ряд преимуществ перед FAT32

  • Может автоматически восстанавливаться в случае ошибок на диске
  • Поддержка жестких дисков с большим объемом улучшена
  • Более безопасная файловая система. Можно использовать шифрование или запрет на какие-либо данные.

Как показала практика, NTFS работает медленнее FAT32, но в обращении с файлами больших размеров работает эффективнее. Также, для NTFS потребуется больше оперативной памяти, компьютеры и прочие устройства с ОЗУ меньше 64 Мб NTFS не поддерживает. Хотя таких компьютеров, скорее всего и не существует.

В итоге, можно сказать следующее, что NTFS рационально использует дисковое пространство и неплохо работает с файлами большого размера, но FAT32 работает быстрее, правда поддерживает работу с файлами только до 4 Гб. NTFS более надежен, FAT32 не требует большого объема оперативной памяти.

Под какую файловую систему форматировать свой жесткий диск или флэшку решать Вам. Также, обсуждаем в комментариях, какая же все таки лучше.

ВЛАДИМИР МЕШКОВ

Архитектура файловой системы FAT

Общая характеристика файловой системы FAT. Структура раздела с файловой системой FAT

Файловая система FAT (File Allocation Table) была разработана Биллом Гейтсом и Марком Макдональдом в 1977 году и первоначально использовалась в операционной системе 86-DOS. Чтобы добиться переносимости программ из операционной системы CP/M в 86-DOS, в ней были сохранены ранее принятые ограничения на имена файлов. В дальнейшем 86-DOS была приобретена Microsoft и стала основой для ОС MS-DOS 1.0, выпущенной в августе 1981 года. FAT была предназначена для работы с гибкими дисками размером менее 1 Мб и вначале не предусматривала поддержки жёстких дисков.

Структура раздела FAT изображена на рисунке.

В файловой системе FAT дисковое пространство логического раздела делится на две области – системную и область данных (см. рис. 1). Системная область создается и инициализируется при форматировании, а впоследствии обновляется при манипулировании файловой структурой. Системная область файловых систем FAT состоит из следующих компонентов:

  • загрузочная запись (boot record, BR);
  • резервная область;
  • таблицы размещения файлов;
  • область корневого каталога (не существует в FAT32).

Область данных логического диска содержит файлы и каталоги, подчиненные корневому, и разделена на участки одинакового размера – кластеры. Кластер может состоять из одного или нескольких последовательно расположенных на диске секторов. Число секторов в кластере должно быть кратно 2N и может принимать значения от 1 до 64. Размер кластера зависит от типа используемой файловой системы и объема логического диска.

Назначение, структура и типы таблицы размещения файлов

Своё название FAT получила от одноимённой таблицы размещения файлов – File Allocation Table, FAT. В таблице размещения файлов хранится информация о кластерах логического диска. Каждому кластеру соответствует элемент таблицы FAT, содержащий информацию о том, свободен данный кластер или занят данными файла. Если кластер занят под файл, то в соответствующем элементе таблицы размещения файлов указывается адрес кластера, содержащего следующую часть файла. Номер начального кластера, занятого файлом, хранится в элементе каталога, содержащего запись об этом файле. Последний элемент списка кластеров содержит признак конца файла (EOF – End Of File). Первые два элемента FAT являются резервными.

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

Существуют следующие типы FAT – FAT12, FAT16, FAT32. Названия типов FAT ведут свое происхождение от размера элемента: элемент FAT12 имеет размер 12 бит (1,5 байт), FAT16 – 16 бит (2 байта), FAT32 – 32 бита (4 байта). В FAT32 четыре старших двоичных разряда зарезервированы и игнорируются в процессе работы операционной системы.

Корневой каталог

За таблицами размещения файлов следует корневой каталог. Каждому файлу и подкаталогу в корневом каталоге соответствует 32-байтный элемент каталога (directory entry), содержащий имя файла, его атрибуты (архивный, скрытый, системный и «только для чтения»), дату и время создания (или внесения в него последних изменений), а также прочую информацию. Для файловых систем FAT12 и FAT16 положение корневого каталога на разделе и его размер жестко зафиксированы. В FAT32 корневой каталог может быть расположен в любом месте области данных раздела и иметь произвольный размер.

Форматы имен файлов

Одной из характеристик ранних версий FAT (FAT12 и FAT16) является использование коротких имен файлов. Короткое имя состоит из двух полей – 8-байтного поля, содержащего собственно имя файла, и 3-байтного поля, содержащего расширение (формат «8.3»). Если введенное пользователем имя файла короче 8 символов, то оно дополняется пробелами (код 0x20); если введенное расширение короче трёх байтов, то оно также дополняется пробелами.

Структура элемента каталога для короткого имени файла представлена в таблице 1.

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

  • если первый байт равен 0xE5, то элемент каталога свободен и его можно использовать при создании нового файла;
  • если первый байт равен 0x00, то элемент каталога свободен и является началом чистой области каталога (после него нет ни одного задействованного элемента).

Таблица 1. Структура элемента каталога для короткого имени файла

Смещение

Размер (байт) Содержание
0x00 11 Короткое имя файла
0x0B 1 Атрибуты файла
0x0C 1 Зарезервировано для Windows NT.
0x0D 1 Поле, уточняющее время создания файла (содержит десятки миллисекунд). Поле обрабатывается только в FAT32
0x0E 1 Время создания файла. Поле обрабатывается только в FAT32
0x10 2 Дата создания файла. Поле обрабатывается только в FAT32
0x12 2 Дата последнего обращения к файлу для записи или считывания данных. Поле обрабатывается только в FAT32
0x14 2 Старшее слово номера первого кластера файла. Поле обрабатывается только в FAT32
0x16 2 Время выполнения последней операции записи в файл
0x18 2 Дата выполнения последней операции записи в файл
0x1A 2 Младшее слово номера первого кластера файла
0x1C 4 Размер файла в байтах

На использование ASCII-символов в коротком имени накладывается ряд ограничений:

  • нельзя использовать символы с кодами меньше 0x20 (за исключением кода 0x05 в первом байте короткого имени);
  • нельзя использовать символы с кодами 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C;
  • нельзя использовать символ пробела (0x20) в первом байте имени.

В файловых системах FAT32 и VFAT (виртуальная FAT, расширение FAT16) включена поддержка длинных имен файлов (long file name, LFN). Для хранения длинного имени используются элементы каталога, смежные с основным элементом. Имя файла записывается не ASCII-символами, а в Unicode. В одном элементе каталога можно сохранить фрагмент длиной до 13 символов Unicode. Неиспользованный участок последнего фрагмента заполняется кодами 0xFFFF. Структура элемента каталога для длинного имени файла представлена в таблице 2.

Таблица 2. Структура элемента каталога для длинного имени файла

Смещение Размер (байт) Содержание
0x00 1 Номер фрагмента
0x01 10 Символы 1-5 имени файла в Unicode
0x0B 1 Атрибуты файла
0x0C 1 Байт флагов
0x0D 1 Контрольная сумма короткого имени
0x0E 12 Символы 6-11 имени файла в Unicode
0x1A 2 Номер первого кластера (заполняется нулями)
0x1C 4 Символы 12-13 имени файла в Unicode

Загрузочный сектор

В первом секторе логического диска с системой FAT располагается загрузочный сектор и блок параметров BIOS. Начальный участок данного блока для всех типов FAT идентичен (таблица 3). Различия в структуре загрузочных секторов для разных типов FAT начинаются со смещения 0x24. Для FAT12 и FAT16 структура имеет вид, показанный в таблице 4, для FAT32 – в таблице 5.

Таблица 3. Начальный участок загрузочного сектора

Смещение Размер, байт Описание
0x00 3 Безусловный переход (jmp) на загрузочный код
0x03 8 Идентификатор фирмы-изготовителя
0x0B 2 Число байт в секторе (512)
0x0D 1 Число секторов в кластере
0x0E 2 Число резервных секторов в резервной области раздела, начиная с первого сектора раздела
0x10 1 Число таблиц (копий) FAT
0x11 2 Для FAT12/FAT16 - количество 32-байтных дескрипторов файлов в корневом каталоге; для FAT32 это поле имеет значение 0
0x13 2 Общее число секторов в разделе; если данное поле содержит 0, то число секторов задается полем по смещению 0x20
0x15 1 Тип носителя. Для жесткого диска имеет значение 0xF8; для гибкого диска (2 стороны, 18 секторов на дорожке) – 0xF0
0x16 2 Для FAT12/FAT16 это поле содержит количество секторов, занимаемых одной копией FAT; для FAT32 это поле имеет значение 0
0x18 2 Число секторов на дорожке (для прерывания 0x13)
0x1A 2 Число рабочих поверхностей (для прерывания 0x13)
0x1C 4 Число скрытых секторов перед разделом
0x20 4 Общее число секторов в разделе. Поле используется, если в разделе свыше 65535 секторов, в противном случае поле содержит 0.

Таблица 4. Структура загрузочного сектора FAT12/FAT16

Смещение Размер, байт Описание 0x24 1 Номер дисковода для прерывания 0х13 0x25 1 0x26 1 Признак расширенной загрузочной записи (0x29) 0x27 4 Номер логического диска 0x2B 11 Метка диска 0x36 8 Текстовая строка с аббревиатурой типа файловой системы

Таблица 5. Структура загрузочного сектора FAT32

Размер, байт Описание 4 Количество секторов, занимаемых одной копией FAT 2 Номер активной FAT 2 Номер версии FAT32: старший байт - номер версии, младший – номер ревизии. В настоящее время используется значение 0:0 4 Номер кластера для первого кластера корневого каталога 2 Номер сектора структуры FSINFO в резервной области логического диска 2 Номер сектора(в резервной области логического диска), используемого для хранения резервной копии загрузочного сектора 12 Зарезервировано (содержит 0)

Смещение
0x24
0x28
0x2A
0x2С
0x30
0x32
0x34

Кроме перечисленных в таблицах 2-го и 3-го полей, нулевой сектор логического диска должен содержать в байте со смещением 0x1FE код 0x55, а в следующем байте (смещение 0x1FF) – код 0xAA. Указанные два байта являются признаком загрузочного диска.

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

На логическом диске с организацией FAT32 дополнительно присутствует структура FSInfo, размещаемая в первом секторе резервной области. Эта структура содержит информацию о количестве свободных кластеров на диске и о номере первого свободного кластера в таблице FAT. Формат структуры описан в таблице 6.

Таблица 6. Структура сектора FSInfo и резервного загрузочного сектора FAT32

Размер, байт Описание 4 Значение 0x41615252 – сигнатура, которая служит признаком того, данный сектор содержит структуру FSInfo 480 Зарезервировано (содержит 0) 4 Значение 0x61417272 (сигнатура) 4 Содержит текущее число свободных кластеров на диске. Если в поле записано значение 0xFFFFFFFF, то число свободных кластеров неизвестно, и его необходимо вычислять 4 Содержит номер кластера, с которого дисковый драйвер должен начинать поиск свободных кластеров. Если в поле записано значение 0xFFFFFFFF, то поиск свободных кластеров нужно начинать с кластера номер 2 12 Зарезервировано (содержит 0) 4 Сигнатура 0xAA550000 – признак конца структуры FSInfo

Смещение
0x000
0x004
0x1E4
0x1E8
0x1EC
0x1F0
0x1FC

Для доступа к содержимому файла, находящемуся на разделе с файловой системой FAT, необходимо получить номер первого кластера файла. Этот номер, как мы уже установили, входит в состав элемента каталога, содержащего запись о файле. Номеру первого кластера соответствует элемент таблицы FAT, в котором хранится адрес кластера, содержащего следующую часть файла. Элемент FAT, соответствующий последнему кластеру в цепочке, содержит сигнатуру конца файла. Для FAT12 это значение составляет 0xFFF, для FAT16 – 0xFFFF, для FAT32 – 0xFFFFFFFF.

Рассмотрим программную реализацию алгоритма чтения для каждого типа FAT, и начнём с FAT16.

Все исходные тексты, рассматриваемые в статье, доступны на сайте журнала.

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT16

Разработаем модуль, выполняющий чтение N первых кластеров файла, созданного на разделе с файловой системой FAT16. Параметр N (число кластеров для считывания) является переменной величиной и задается пользователем. Имя файла соответствует формату «8.3», т.е. является коротким. Модуль функционирует под управлением ОС Linux.

Определим необходимые заголовочные файлы:

#include

#include

#include

#include

#include

#include "split.h"

Заголовочный файл split.h имеет следующее содержание:

#include

#define SHORT_NAME 13 // максимальная длина короткого имени файла

struct split_name {

U8 name; // имя файла

U8 ext; // расширение файла

Int name_len, // длина имени файла

Ext_len; // длина расширения файла

Cтруктура split_name предназначена для хранения составных частей короткого имени файла (имени и расширения) и их длин.

В заголовочном файле определены структурные типы, описывающие основные компоненты файловой системы FAT – загрузочный сектор, сектор FSInfo, структуры элементов каталога для короткого и длинного имён файлов.

Рассмотрим кратко поля, которые входят в каждую из этих структур.

    1. Структура загрузочного сектора struct fat_boot_sector:
      • __s8 system_id – системный идентификатор;
      • __u8 sector_size – размер сектора в байтах;
      • __u8 cluster_size – размер кластера в секторах;
      • __u16 reserved – число резервных секторов в резервной области раздела;
      • __u8 fats – количество копий FAT;
      • __u8 dir_entries – количество 32-байтных дескрипторов файлов в корневом каталоге;
      • __u8 sectors – число секторов на разделе; если это поле равно 0, используется поле total_sect;
      • __u8 media – тип носителя, на котором создана файловая система;
      • __u16 fat_length – размер FAT в секторах;
      • __u32 total_sect – размер раздела FAT в секторах (если поле sectors == 0).
      • __u32 fat32_length – размер FAT32 в секторах;
      • __u32 root_cluster – номер первого кластера корневого каталога;
      • __u16 info_sector – номер сектора, содержащего структуру FSInfo.

Следующие поля данной структуры используются только FAT32:

  1. Структура сектора FSInfo struct fat_boot_fsinfo:
    • __u32 signature1 – сигнатура 0x41615252;
    • __u32 signature2 – сигнатура 0x61417272;
    • __u32 free_clusters – количество свободных кластеров. Если поле содержит -1, поиск свободных кластеров нужно начинать с кластера номер 2.
  2. Структура элемента каталога короткого имени struct msdos_dir_entry:
    • __s8 name,ext – имя и расширение файла;
    • __u8 attr – атрибуты файла;
    • __u8 ctime_ms – это поле уточняет время создания файла до мс (используется только FAT32);
    • __u16 ctime – время создания файла (используется только FAT32);
    • __u16 cdate – дата создания файла (используется только FAT32);
    • __u16 adate – дата последнего доступа к файлу (используется только FAT32);
    • __u16 starthi – старшие 16 бит номера первого кластера файла (используется только FAT32);
    • __u16 time,date,start – время и дата создания файла, номер первого кластер файла;
    • __u32 size – размер файла (в байтах).
  3. Структура элемента каталога длинного имени:
    • __u8 id – номер элемента;
    • __u8 name0_4 – символы 1 – 5 имени;
    • __u8 attr – атрибуты файла;
    • __u8 alias_checksum – контрольная сумма короткого имени;
    • __u8 name5_10 – символы 6 – 11 имени;
    • __u8 name11_12 – символы 12 – 13 имени.

Продолжим рассмотрение программной реализации алгоритма и определим имя раздела, на котором создана файловая система FAT16:

#ifndef FAT16_PART_NAME

#define FAT16_PART_NAME "/dev/hda1"

#endif

Глобальные структуры:

struct fat_boot_sector fbs; // структура загрузочного сектора

struct msdos_dir_entry dentry; // структура элемента каталога

Глобальные переменные:

U16 *fat16; // сюда копируем таблицу FAT16

U16 sector_size; // размер сектора (из FAT16)

U16 dir_entries; // число 32-байтных дескрипторов

// в root-каталоге (0 для FAT32)

U16 sectors; // общее число секторов в разделе

U32 fat16_size; // размер FAT16

U32 root_size; // размер корневого каталога

U16 byte_per_cluster; // размер кластера в байтах

U16 next_cluster; // очередной кластер в цепочке

int fat;

Начнём рассмотрение с главной функции:

int main()

Int num;

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

U8 *full_path = "/Folder1/Folder2/text.txt";

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

Hard = open(FAT16_PART_NAME, O_RDONLY);

If(hard < 0) {

Perror(FAT16_PART_NAME);

Exit(-1);

Считываем первые 10 кластеров файла. Считывание выполняет функция fat16_read_file(). Параметры функции – полное имя файла и число кластеров для чтения. Функция возвращает число прочитанных кластеров или -1, если при чтении произошла ошибка:

Num = fat16_read_file(full_path, 10);

If(num < 0) perror("fat16_read_file");

Else printf("Read %d clusters ", num);

Закрываем файл устройства и выходим:

Close(hard);

Return 0;

Функция чтения кластеров файла имеет следующий вид:

int fat16_read_file(__u8 *full_path, int num)

Struct split_name sn; // структура для хранения составных частей файла

U8 tmp_name_buff; // буфер для временного хранения составных элементов полного пути файла

Static int i = 1;

Int n;

U8 *tmp_buff;

U16 start_cluster, next_cluster;

Параметры функции мы перечислили при рассмотрении функции main.

Подготовительные операции – обнуляем буфер tmp_name_buff и структуру struct split_name sn:

Первым символом в абсолютном путевом имени файла должен быть прямой слэш (/). Проверяем это:

Считываем с раздела загрузочный сектор:

If(read_fbs() < 0) return -1;

Считанный загрузочный сектор находится сейчас в глобальной структуре struct fat_boot_sector fbs. Скопируем из этой структуры размер сектора, число записей в корневом каталоге и общее число секторов на разделе:

Определим размер кластера в байтах:

Byte_per_cluster = fbs.cluster_size * 512

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

Printf("System id - %s ", fbs.system_id);

Printf("Sector size - %d ", sector_size);

Printf("Cluster size - %d ", fbs.cluster_size);

Printf("Reserved - %d ", fbs.reserved);

Printf("FATs number - %d ",fbs.fats);

Printf("Dir entries - %d ", dir_entries);

Printf("Sectors - %d ", sectors);

Printf("Media - 0x%X ", fbs.media);

Printf("FAT16 length - %u ", fbs.fat_length);

Printf("Total sect - %u ", fbs.total_sect);

Printf("Byte per cluster - %d ", byte_per_cluster);

Вычисляем размер FAT16 в байтах и считываем её:

Fat16_size = fbs.fat_length * 512;

If(read_fat16() < 0) return -1;

Считываем корневой каталог:

If(read_root_dentry() < 0) return -1;

Сейчас указатель dir_entry позиционирован на область памяти, содержащую записи корневого каталога. Размер этой области памяти равен размеру корневого каталога (root_size).

Сохраним (для контроля) содержимое корневого каталога в отдельном файле:

#ifdef DEBUG

Close(fat);

#endif

Вычисляем начало области данных:

Data_start = 512 * fbs.reserved + fat16_size * fbs.fats + root_size;

Имея все записи корневого каталога, мы можем добраться до содержимого файла test.txt. С этой целью организуем цикл. В теле цикла проведем разбор полного имени файла, выделяя его элементы – подкаталоги (их у нас два, Folder1 и Folder2) и имя искомого файла (test.txt).

While(1) {

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

For(n = 0 ; n < SHORT_NAME; n++, i++) {

If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "?")) {

I++;

Break;

Tmp_name_buff[n] = "?";

Заполняем структуру struct split_name sn соответствующей информацией. Заполнение выполняет функция split_name, при этом выполняется проверка имени файла на соответствие формату «8.3»:

< 0) {

Printf("not valid name ");

Return -1;

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

If(get_dentry(&sn) < 0) {

Printf("No such file! ");

Return -1;

Проверяем атрибуты файла. Если это каталог, считываем его содержимое и продолжаем цикл:

If(dentry.attr & 0x10) {

If(read_directory(dentry.start) < 0) return -1;

Continue;

Если это файл – считываем первые num кластеров. Для контроля считанную информацию сохраним в отдельном файле:

If(dentry.attr & 0x20) {

Start_cluster = dentry.start;

Tmp_buff = (__u8 *)malloc(byte_per_cluster); // сюда будет считываться содержимое кластера

N = open("clust", O_CREAT|O_RDWR, 0600); // в этом файле сохраним считанную информацию

If(n < 0) {

Perror("open");

Return -1;

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

For(i = 0; i < num; i++) {

Считываем содержимое кластера в буфер tmp_buff и сохраняем его в отдельном файле:

< 0) return -1;

< 0) {

Perror("write");

Close(n);

Return -1;

Считываем из FAT16 номер следующего кластера, занятого под данный файл. Если это последний кластер – прерываем цикл и возвращаемся в главную функцию:

#ifdef DEBUG

Printf("OK. Readed ");

Printf("file`s next cluster - 0x%X .. ", next_cluster);

#endif

If(next_cluster == EOF_FAT16) {

#ifdef DEBUG

Printf("last cluster. ");

#endif

Free(tmp_buff);

Close(n);

Return ++i;

#ifdef DEBUG

Printf("stop reading ");

#endif

Return i;

Чтение загрузочного сектора FAT16 выполняет функция read_fbs(). Результат помещается в глобальную структуру fbs:

int read_fbs()

If(read(hard,(__u8 *)&fbs, sizeof(fbs)) < 0) return -1;

Return 0;

Чтение таблицы размещения файлов файловой системы FAT16 выполняет функция read_fat16():

int read_fat16()

U64 seek = (__u64)(fbs.reserved) * 512; // смещение к FAT16 от начала раздела

Fat16 = (void *)malloc(fat16_size);

If(pread64(hard, (__u8 *)fat16, fat16_size, seek) < 0) return -1;

Return 0;

Чтение корневого каталога выполняет функция read_root_dentry():

int read_root_dentry()

U64 seek = (__u64)fbs.reserved * 512 + fat16_size * fbs.fats; // смещение к корневому каталогу от начала раздела

Root_size = 32 * dir_entries; // вычисляем размер корневого каталога

Dir_entry = (__u8 *)malloc(root_size);

If(!dir_entry) return -1;

Memset(dir_entry, 0, root_size);

If(pread64(hard, dir_entry, root_size, seek) < 0) return -1;

Return 0;

Чтение кластера, принадлежащего файлу, выполняет функция read_cluster(). Входные параметры функции – номер кластера cluster_num и указатель на буфер __u8 *tmp_buff, куда нужно поместить результат чтения. Смещение к кластеру на разделе вычисляется по формуле (см. ):

SEEK = DATA_START + (CLUSTER_NUM - 2) * BYTE_PER_CLUSTER,

  • SEEK – смещение к кластеру на разделе
  • DATA_START – начало области данных
  • CLUSTER_NUM – порядковый номер кластера
  • BYTE_PER_CLUSTER – размер кластера в байтах

int read_cluster(__u16 cluster_num, __u8 *tmp_buff)

U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start; // вычисляем смещение к кластеру

< 0) return -1;

Return 0;

Функция read_directory выполняет чтение записей каталога (не корневого) и помещает результат в область памяти, на которую настроен указатель dir_entry:

int read_directory(__u16 start_cluster)

Int i = 1;

U16 next_cluster;

For(; ;i++) {

Выделяем память для хранения содержимого каталога, считываем содержимое стартового кластера и получаем из таблицы FAT16 значение очередного кластера:

If(!dir_entry) return -1;

< 0) return -1;

Next_cluster = fat16;

Сохраним содержимое каталога в отдельном файле (для контроля):

#ifdef DEBUG

Printf("Next cluster - 0x%X ", next_cluster);

Fat = open("dir16", O_CREAT|O_WRONLY, 0600);

Write(fat, dir_entry, root_size);

Close(fat);

#endif

Если достигнут последний кластер, выходим из цикла, иначе продолжаем чтение каталога, увеличив размер буфера dir_entry ещё на один кластер:

If(next_cluster & EOF_FAT16) break;

Start_cluster = next_cluster;

Return 0;

Поиск в содержимом каталога элемента, соответствующего искомому файлу, выполняет функция get_dentry(). Входные параметры этой функции – указатель на структуру struct split_name *sn, содержащую элементы короткого имени файла:

Int i = 0;

В глобальном буфере dir_entry находится массив элементов каталога, в котором мы собираемся искать запись файла (или каталога). Для поиска организуем цикл. В теле цикла производим копирование элементов каталога в глобальную структуру dentry и сравниваем значение полей name и ext этой структуры с соответствующими полями структуры struct split_name *sn. Совпадение этих полей означает, что мы нашли в массиве элементов каталога запись искомого файла:

for(; ; i++) {

If(!(memcmp(dentry.name, sn->name, sn->name_len)) &&

!(memcmp(dentry.ext, sn->ext, sn->ext_len)))

Break;

If(!dentry.name) return -1;

#ifdef DEBUG

Printf("name - %s ", dentry.name);

Printf("start cluster - 0x%X ", dentry.start);

Printf("file size - %u ", dentry.size);

Printf("file attrib - 0x%X ", dentry.attr);

#endif

Return 0;

Весь вышеприведенный код находится в каталоге FAT16, файл fat16.c. Для получения исполняемого модуля создадим Makefile следующего содержания:

INCDIR = /usr/src/linux/include

PHONY = clean

Fat16: fat16.o split.o

Gcc -I$(INCDIR) $^ -g -o $@

%.o: %.c

Gcc -I$(INCDIR) -DDEBUG -c $^

Clean:

Rm -f *.o

Rm -f ./fat16

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT12

В целом алгоритм чтения файла с раздела FAT12 идентичен алгоритму чтения файла с раздела FAT16. Отличие заключается в процедуре чтения элементов из таблицы FAT12. Таблица FAT16 рассматривалась нами как простой массив 16-разрядных элементов. Для чтения элементов таблицы FAT12 в предложен следующий алгоритм:

  • умножить номер элемента на 1.5;
  • извлечь из FAT 16-разрядное слово, используя в качестве смещения результат предыдущей операции;
  • если номер элемента четный, выполнить операцию AND над считанным словом и маской 0x0FFF. Если номер нечетный, сдвинуть считанное из таблицы слово на 4 бита в сторону младших разрядов.

Базируясь на этом алгоритме, реализуем функцию чтения элементов из таблицы FAT12:

int get_cluster(__u16 cluster_num)

U16 seek;

U16 clust;

Вычисляем смещение в таблице FAT12 и считываем из таблицы 16-разрядное слово:

Seek = (cluster_num * 3) / 2;

Memcpy((__u8 *)&clust, (__u8 *)(fat12 + seek), 2);

Если стартовый номер кластера – четное число, сдвигаем считанное из таблицы значение на 4 бита в сторону младших разрядов, если нечетное – суммируем его с 0x0FFF:

If(cluster_num % 2) clust >>= 4;

Else clust &= 0x0FFF;

Этот фрагмент можно также реализовать на ассемблере:

" xorw %%ax, %%ax "

" btw $0, %%cx "

" jnc 1f "

" shrw $4, %%dx "

" jmp 2f "

"1: andw $0x0FFF, %%dx "

"2: movw %%dx, %%ax "

:"=a" (next)

:"d" (clust), "c" (cluster_num));

Возвращаем результат:

Return clust;

Остановимся чуть подробнее на самом алгоритме. Предположим, что на разделе с FAT12 создан файл, который занимает 9-й и 10-й кластеры. Каждый элемент FAT12 занимает 12 бит. Т.к. из таблицы мы считываем 16-разрядные элементы, то смещение к 9-му элементу будет равно 13 байт (9 * 1.5 = 13, остаток отбрасываем), при этом младшие 4 разряда будут принадлежать 8-му элементу FAT. Их необходимо отбросить, а для этого достаточно сдвинуть считанный элемент на 4 бита в сторону младших разрядов, что и предусмотрено алгоритмом. Смещение к 10-му элементу будет равно 15 байт, и старшие 4 бита будут принадлежать 11-му элементу FAT. Чтобы их отбросить, необходимо выполнить операцию AND над 10-м элементом и маской 0x0FFF, что так же соответствует вышеприведенному алгоритму.

Исходные тексты модуля чтения файла с раздела FAT12 находятся в каталоге FAT12, файл fat12.c.

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT32

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

Логическая структура жесткого диска

Рассмотрим логическую структуру жесткого диска, соответствующую стандарту Microsoft – «основной раздел – расширенный раздел – разделы non-DOS».

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

На жестком диске по физическому адресу 0-0-1 располагается главная загрузочная запись (Master Boot Record, MBR). В структуре MBR находятся следующие элементы:

  • внесистемный загрузчик (non-system bootstrap – NSB);
  • таблица описания разделов диска (таблица разделов, partition table, PT). Располагается в MBR по смещению 0x1BE и занимает 64 байта;
  • сигнатура MBR. Последние два байта MBR должны содержать число 0xAA55.

Таблица разделов описывает размещение и характеристики имеющихся на винчестере разделов. Разделы диска могут быть двух типов – primary (первичный, основной) и extended (расширенный). Максимальное число primary-разделов равно четырем. Наличие на диске хотя бы одного primary-раздела является обязательным. Extended-раздел может быть разделен на большое количество подразделов – логических дисков. Упрощенно структура MBR представлена в таблице 7. Таблица разделов располагается в конце MBR, для описания раздела в таблице отводится 16 байт.

Таблица 7. Структура MBR

Смещение Размер, байт 0 446 0x1BE 16 0x1CE 16 0x1DE 16 0x1EE 16 0x1FE 2

Структура записи элемента таблицы разделов показана в таблице 8.

Таблица 8. Структура записи элемента таблицы разделов

Смещение Размер, байт Содержание
0x00 1 Признак активности (0 - раздел не активный, 0x80 – раздел активный)
0x01 1 Номер головки диска, с которой начинается раздел
0x02 2 Номер цилиндра и номер сектора, с которых начинается раздел
0x04 1 Код типа раздела System ID
0x05 1 Номер головки диска, на которой заканчивается раздел
0x06 2 Номер цилиндра и номер сектора, которыми заканчивается раздел
0x08 4 Абсолютный (логический) номер начального сектора раздела
0x0C 4 Размер раздела (число секторов)

Первым байтом в элементе раздела идет флаг активности раздела (0 – неактивен, 0x80 – активен). Он служит для определения, является ли раздел системным загрузочным и есть ли необходимость производить загрузку операционной системы с него при старте компьютера. Активным может быть только один раздел. За флагом активности раздела следуют координаты начала раздела – три байта, означающие номер головки, номер сектора и номер цилиндра. Номера цилиндра и сектора задаются в формате прерывания Int 0x13, т.е. биты 0-5 содержат номер сектора, биты 6-7 – старшие два бита 10-разрядного номера цилиндра, биты 8-15 – младшие восемь бит номера цилиндра. Затем следует кодовый идентификатор System ID, указывающий на принадлежность данного раздела к той или иной операционной системе. Идентификатор занимает один байт. За системным идентификатором расположены координаты конца раздела – три байта, содержащие номера головки, сектора и цилиндра соответственно. Следующие четыре байта – это число секторов перед разделом, и последние четыре байта – размер раздела в секторах.

Таким образом, элемент таблицы раздела можно описать при помощи следующей структуры:

struct pt_struct {

U8 bootable; // флаг активности раздела

U8 start_part; // координаты начала раздела

U8 type_part; // системный идентификатор

U8 end_part; // координаты конца раздела

U32 sect_before; // число секторов перед разделом

U32 sect_total; // размер раздела в секторах (число секторов в разделе)

Элемент первичного раздела указывает сразу на загрузочный сектор логического диска (в первичном разделе всегда имеется только один логический диск), а элемент расширенного раздела – на список логических дисков, составленный из структур, которые именуются вторичными MBR (Secondary MBR, SMBR).

Свой блок SMBR имеется у каждого диска расширенного раздела. SMBR имеет структуру, аналогичную MBR, но загрузочная запись у него отсутствует (заполнена нулями), а из четырех полей описателей разделов используются только два. Первый элемент раздела при этом указывает на логический диск, второй элемент указывает на следующую структуру SMBR в списке. Последний SMBR списка содержит во втором элементе нулевой код раздела.

Вернемся к рассмотрению модуля чтения файла с раздела FAT32.

Заголовочные файлы:

#include

#include

#include

#include

#include

Сигнатура MBR:

#define SIGNATURE 0xAA55

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

#define DEVICE "/dev/hda"

Размер элемента таблицы разделов (16 байт):

#define PT_SIZE 0x10

Следующий массив структур устанавливает соответствие между кодом типа раздела и его символьным отображением:

struct systypes {

U8 part_type;

U8 *part_name;

struct systypes i386_sys_types = {

{0x00, "Empty"},

{0x01, "FAT12"},

{0x04, "FAT16 <32M"},

{0x05, "Extended"},

{0x06, "FAT16"},

{0x0b, "Win95 FAT32"},

{0x0c, "Win95 FAT32 (LBA)"},

{0x0e, "Win95 FAT16 (LBA)"},

{0x0f, "Win95 Ext"d (LBA)"},

{0x82, "Linux swap"},

{0x83, "Linux"},

{0x85, "Linux extended"},

{0x07, "HPFS/NTFS"}

Определим число элементов в массиве i386_sys_types при помощи макроса PART_NUM:

#define PART_NUM (sizeof(i386_sys_types) / sizeof(i386_sys_types))

Установим ограничение на количество логических дисков:

#define MAX_PART 20

Следующий массив структуры будет содержать информацию о логических дисках на устройстве (жестком диске):

struct pt_struct {

U8 bootable;

U8 start_part;

U8 type_part;

U8 end_part;

U32 sect_before;

U32 sect_total;

} pt_t;

int hard; // дескриптор файла устройства

U8 mbr; // сюда считаем MBR

Номер раздела, на котором создана файловая система FAT32:

#define FAT32_PART_NUM 5

Структуры загрузочного сектора, сектора FSInfo и элемента каталога (определены в файле ):

struct fat_boot_sector fbs;

struct fat_boot_fsinfo fsinfo;

struct msdos_dir_entry dentry;

U32 *fat32 = NULL; // сюда копируем таблицу FAT32

U16 sector_size; // размер сектора (из FAT32)

U16 dir_entries; // 0 для FAT32

U16 sectors; // число секторов на разделе

U32 fat32_size; // размер FAT32

U32 data_start; // начало области данных

U16 byte_per_cluster; // сколько байт в кластере (размер кластера в байтах)

U32 next_cluster; // очередной кластер в цепочке

U32 root_cluster; // ROOT cluster - начальный кластер корневого каталога

U8 *dir_entry = NULL; // указатель на записи каталога

U64 start_seek = 0; // стартовое смещение к разделу (в байтах)

Главная функция:

int main()

Int num = 0;

Int cluster_num = 5; // сколько кластеров считывать из файла

U8 *full_path = "/Folder1/Folder2/readme"; // файл для считывания

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

Hard = open(DEV_NAME, O_RDONLY);

If(hard < 0) {

Perror(DEV_NAME);

Exit(-1);

If(get_pt_info(hard) < 0) {

Perror("get_pt_info");

Exit(-1);

Show_pt_info();

Вычисляем стартовое смещение к разделу:

Start_seek = (__u64)(pt_t.sect_before) * 512;

Считываем кластеры, принадлежащие файлу:

Num = fat32_read_file(full_path, cluster_num);

If(num < 0) perror("fat32_read_file");

Else printf("Read %d clusters\n", num);

Close(hard);

Return 0;

Информацию о таблице разделов считывает функция get_pt_info():

int get_pt_info(int hard)

Int i = 0;

U64 seek;

Считываем таблицу разделов из MBR и проверяем сигнатуру:

Read_main_ptable(hard);

If(check_sign() < 0) {

Printf("Not valid signature!\n");

Return -1;

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

for(; i < 4; i++) {

If((pt_t[i].type_part == 0xF) || \

(pt_t[i].type_part == 0x5) || \

(pt_t[i].type_part == 0x0C)) {

Seek = (__u64)pt_t[i].sect_before * 512;

Read_ext_ptable(hard, seek);

Break;

Return 0;

Функция чтения таблицы разделов read_main_ptable():

void read_main_ptable(int hard)

If(read(hard, mbr, 512) < 0) {

Perror("read");

Close(hard);

Exit(-1);

Memset((void *)pt_t, 0, (PT_SIZE * 4));

Memcpy((void *)pt_t, mbr + 0x1BE, (PT_SIZE * 4));

Return;

Функция проверки сигнатуры check_sign():

int check_sign()

U16 sign = 0;

Memcpy((void *)&sign, (void *)(mbr + 0x1FE), 2);

#ifdef DEBUG

Printf("Signature - 0x%X\n", sign);

#endif

If(sign != SIGNATURE) return -1;

Return 0;

Функция чтения расширенной таблицы разделов:

void read_ext_ptable(int hard, __u64 seek)

Int num = 4; // начиная с этой позиции, массив структур pt_t будет заполняться информацией о логических дисках

U8 smbr;

Входные данные:

  • hard – дескриптор файла устройства;
  • seek – смещение к расширенному разделу от начала диска (в байтах).

Для получения информации о логических дисках организуем цикл:

For(;;num++) {

Считываем SMBR, находящуюся по смещению seek от начала диска:

Memset((void *)smbr, 0, 512);

Pread64(hard, smbr, 512, seek);

Заполняем два элемента таблицы pt_t, начиная с позиции num. Первый элемент будет указывать на логический диск, а второй – на следующую структуру SMBR:

Memset((void *)&pt_t, 0, PT_SIZE * 2);

Memcpy((void *)&pt_t, smbr + 0x1BE, PT_SIZE * 2);

Вносим поправку в поле «Номер начального сектора» – отсчет ведется от начала диска:

Pt_t.sect_before += (seek / 512);

Если код типа раздела равен нулю, то больше логических дисков нет:

If(!(pt_t.type_part)) break;

Вычисляем смещение к следующему SMBR:

Seek = ((__u64)(pt_t.sect_before + pt_t.sect_total)) * 512;

Return;

Функция show_pt_info() отображает информацию о найденных логических дисках на устройстве:

void show_pt_info()

Int i = 0, n;

#ifdef DEBUG

Printf("Число разделов на диске - %d\n", PART_NUM);

#endif

For(; i < MAX_PART; i++) {

If(!pt_t[i].type_part) break;

Printf("\nТип раздела %d - ", i);

For(n = 0; n < PART_NUM; n++) {

If(pt_t[i].type_part == i386_sys_types[n].part_type) {

Printf("%s\n", i386_sys_types[n].part_name);

Break;

If(n == PART_NUM) printf("unknown type\n");

Printf("Признак загрузки - 0x%X\n", pt_t[i].bootable);

Printf("Секторов в разделе %d - %d\n", i, pt_t[i].sect_total);

Printf("Секторов перед разделом %d - %d\n\n", i, pt_t[i].sect_before);

Return;

Чтение кластеров файла с раздела FAT32 выполняет функция fat32_read_file(). Эта функция имеет много общего с функцией fat16_read_file(), поэтому за подробными комментариями обратитесь к п. 6:

int fat32_read_file(__u8 *full_path, int num)

Struct split_name sn;

U8 tmp_name_buff;

Int i = 1, n;

U32 start_cluster, next_cluster;

U8 *tmp_buff;

Подготовительные операции – чистим буфер, структуру и проверяем первый слэш:

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

If(full_path != "/") return -1;

Считываем загрузочный сектор:

If(read_fbs() < 0) return -1;

Memcpy((void *)§or_size, (void *)fbs.sector_size, 2);

Memcpy((void *)&dir_entries, (void *)fbs.dir_entries, 2);

Memcpy((void *)§ors, (void *)fbs.sectors, 2);

Считываем структуру FSInfo и отобразим сигнатуру, находящуюся в ней:

If(read_fs_info() < 0) return -1;

Printf("Signature1 - 0x%X\n", fsinfo.signature1);

Printf("Signature2 - 0x%X\n", fsinfo.signature2);

Fat32_size = fbs.fat32_length * 512; // размер FAT32 в байтах

Data_start = 512 * fbs.reserved + fat32_size * 2; // начало поля данных

Byte_per_cluster = fbs.cluster_size * 512; // размер кластера в байтах

Root_cluster = fbs.root_cluster; // номер кластера корневого каталога

Считываем FAT32:

If(read_fat32() < 0) return -1;

Выделяем память для записей каталога:

Dir_entry = (__u8 *)malloc(byte_per_cluster);

If(!dir_entry) return -1;

Считываем корневой каталог:

If(read_directory(root_cluster) < 0) return -1;

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

While(1) {

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

For(n = 0 ; n < SHORT_NAME; n++, i++) {

Tmp_name_buff[n] = full_path[i];

If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "\0")) {

I++;

Break;

Tmp_name_buff[n] = "\0";

If(split_name(tmp_name_buff, &sn) < 0) {

Printf("not valid name\n");

Return -1;

If(get_dentry(&sn) < 0) {

Printf("No such file!\n");

Return -1;

Для получения стартового номера кластера в файловой системе FAT32 необходимо задействовать старшее слово номера первого кластера файла – поле starthi структуры dentry:

Start_cluster = (((__u32)dentry.starthi << 16) | dentry.start);

Проверяем байт атрибутов:

If(dentry.attr & 0x10) { // это каталог

If(read_directory(start_cluster) < 0) return -1;

Continue;

If(dentry.attr & 0x20) { // а это - файл

Tmp_buff = (__u8 *)malloc(byte_per_cluster);

N = open("clust", O_CREAT|O_RDWR, 0600);

If(n < 0) {

Perror("open");

Return -1;

Printf("file`s first cluster - 0x%X .. ", start_cluster);

For(i = 0; i < num; i++) {

Memset(tmp_buff, 0, byte_per_cluster);

If(read_cluster(start_cluster, tmp_buff) < 0) return -1;

If(write(n, tmp_buff, byte_per_cluster) < 0) {

Perror("write");

Return -1;

If(next_cluster == EOF_FAT32) {

Free(tmp_buff);

Close(n);

Return ++i;

Start_cluster = next_cluster;

Return i;

Назначение следующих трёх функций – получить содержимое системной области, т.е. загрузочного сектора, структуры FSInfo и таблицы FAT32:

1) функция read_fbs() выполняет чтение загрузочного сектора:

int read_fbs()

If(pread64(hard, (__u8 *)&fbs, sizeof(fbs), start_seek) < 0) return -1;

Return 0;

2) функция read_fs_info() считывает структуру FSInfo:

int read_fs_info()

U64 seek = (__u64)fbs.info_sector * 512 + start_seek;

If(pread64(hard, (__u8 *)&fsinfo, sizeof(fsinfo), seek) < 0) return -1;

Return 0;

3) функция read_fat32() считывает таблицу FAT32:

int read_fat32()

U64 seek = (__u64)fbs.reserved * 512 + start_seek;

Fat32 = (void *)malloc(fat32_size);

If(!fat32) return -1;

If(pread64(hard, (__u8 *)fat32, fat32_size, seek) < 0) return -1;

Return 0;

Функция read_cluster() выполняет чтения кластера с указанным номером:

int read_cluster(__u32 cluster_num, __u8 *tmp_buff)

U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start + start_seek;

If(pread64(hard, tmp_buff, byte_per_cluster, seek) < 0) return -1;

Return 0;

Чтением каталогов (в том числе и корневого) занимается функция read_directory():

int read_directory(__u32 start_cluster)

Int i = 2;

U32 next_cluster;

Параметры функции – стартовый кластер каталога. Считываем содержимое каталога в глобальный буфер dir_entry:

If(read_cluster(start_cluster, dir_entry) < 0) return -1;

Next_cluster = fat32;

Если каталог занимает один кластер – выходим, если нет – увеличиваем размер памяти и продолжаем чтение:

For(; ;i++) {

Start_cluster = next_cluster;

Dir_entry = (__u8 *)realloc(dir_entry, i * byte_per_cluster);

If(!dir_entry) return -1;

If(read_cluster(start_cluster, (dir_entry + (i - 1) * byte_per_cluster)) < 0) return -1;

Next_cluster = fat32;

If((next_cluster == EOF_FAT32) || (next_cluster == 0xFFFFFF8)) return 0;

Return 0;

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

int get_dentry(struct split_name *sn)

Int i = 0;

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

For(;;i++) {

Memcpy((void *)&dentry, dir_entry + i * sizeof(dentry), sizeof(dentry));

If(!(memcmp(dentry.name, sn->name, sn->name_len)) &&

!(memcmp(dentry.ext, sn->ext, sn->ext_len)))

Break;

If(!dentry.name) return -1;

Return 0;

На этом рассмотрение модуля чтения файла с раздела FAT32 завершим.

Исходные тексты модуля находятся в каталоге FAT32, файл fat32.c.

Отличия в организации хранения записей о файлах в каталогах для файловых систем FAT и EXT2

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

C FAT мы только что ознакомились – в ней все элементы каталога имеют фиксированную величину. При создании файла драйвер файловой системы ищет первую незанятую позицию и заполняет её информацией о файле. Если длина каталога не умещается в одном кластере, то под него отводится ещё один кластер и т. д.

Рассмотрим, как обстоят дела в EXT2.

Предположим, у нас есть раздел с файловой системой EXT2, размер блока равен 4096 байт. На этом разделе мы создаем каталог. Размер каталога будет равен размеру блока – 4096 байт. В каталоге операционная система сразу создаёт две записи – запись текущего и запись родительского каталогов. Запись текущего каталога займет 12 байт, в то время как длина записи родительского будет равна 4084 байта. Создадим в этом каталоге какой-нибудь файл. После этого в каталоге будут присутствовать три записи – запись текущего каталога длиной 12 байт, запись родительского каталога длиной уже 12 байт, и запись созданного файла длиной, как вы наверно догадались, 4072 байт. Если мы удалим созданный файл, длина записи родительского каталога опять возрастёт до 4084 байт.

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

И в заключение – небольшая правка к статье «Архитектура файловой системы EXT2» .

Эта правка касается функции определения номера inode по имени файла get_i_num(). Старый вариант этой функции выглядел так:

int get_i_num(char *name)

Int i = 0, rec_len = 0;

Struct ext2_dir_entry_2 dent;

For(; i < 700; i++) {

If(!memcmp(dent.name, name, dent.name_len)) break;

Rec_len += dent.rec_len;

Return dent.inode;

Исправленный вариант:

int get_i_num(char *name)

* Параметр функции - имя файла. Возвращаемое значение - номер inode файла.

Int rec_len = 0;

Struct ext2_dir_entry_2 dent; // эта структура описывает формат записи корневого каталога:

* В глобальном буфере buff находится массив записей каталога. Для определения порядкового номера inode файла необходимо найти

* в этом массиве запись с именем этого файла. Для этого организуем цикл:

For(;;) {

/* Копируем в структуру dent записи каталога: */

Memcpy((void *)&dent, (buff + rec_len), sizeof(dent));

* Длина имени файла равная нулю означает, что мы перебрали все записи каталога

* и записи с именем нашего файла не нашли. Значит, пора возвращаться:

If(!dent.name_len) return -1;

/* Поиск выполняется путем сравнения имен файлов. Если имена совпадают - выходим из цикла: */

If(!memcmp(dent.name, name, strlen(name))) break;

/* Если имена не совпали - смещаемся к следующей записи: */

Rec_len += dent.rec_len;

/* В случае успеха возвращаем номер inode файла: */

Return dent.inode;

Литература:

  1. В.Кулаков. Программирование на аппаратном уровне: специальный справочник. 2-е изд. / – СПб.: Питер, 2003 г. – 848 с.
  2. А.В.Гордеев, А.Ю.Молчанов. Системное программное обеспечение / – СПб.: Питер – 2002 г.
  3. Мешков В. Архитектура файловой системы ext2. – Журнал «Системный администратор», № 11(12), ноябрь 2003 г. – 26-32 с.

Вконтакте

Друзья, те из вас, кто использует для установки Windows не официальные её дистрибутивы, образы от Microsoft, а выложенные на торрент-трекерах модифицированные сборки, возможно, задавались вопросом – а ? Но если даже такой вопрос на ум не приходил, то наверняка многих после установки проблемной сборки посещало желание рассказать её горе-сборщику, что они о нём думают, и куда тому нужно идти. Так называемые облегчённые сборки – дистрибутивы с вырезанным или отключённым функционалом, предназначенные для маломощных компьютеров, оптимизированные для игр или прочих специфических задач, по части быстродействия редко когда ощутимо отличаются от обычных дистрибутивов. Зато такие сборки точно доставят проблем, когда понадобятся отсутствующие функции Windows. Как говорится, хочешь, чтобы было всё нормально – сделай дело сам. Ниже рассмотрим, как создаются модифицированные сборки системы с каким-то удалённым, а каким-то добавленным функционалом. И попытаемся собрать свой дистрибутив Windows с помощью программы NTLite.

Зачем создавать свои сборки Windows

В , в принципе, нет ничего плохого. Но лишь при условии, что вырезана действительно ненужная часть дистрибутива, и система остаётся работоспособной по части взаимодействия с аппаратной начинкой и предоставлении доступа к основному функционалу. На 100% угадать, что нужно вырезать, а что оставить в системе, для большой аудитории, естественно, не получится. Но сделать это для себя, для пары-тройки имеющихся в доме компьютерных устройств можно. Для этого нужно точно знать, какой системный функционал никогда не пригодится. А, следовательно, необходимо хотя бы поверхностно разбираться в нём – какие компоненты и службы для чего нужны, что решают те или иные настройки Windows. Но это если вырезать функционал.

Делать первые шаги на поприще создания модифицированных сборок Windows можно ведь и без вырезания функционала системы. А, наоборот, с расширением её возможностей - с добавлением драйверов комплектующих (и даже периферии), с установкой полезных программ. Собственно, для этих целей и существует специальный софт типа NTLite.

О программе NTLite

Программа NTLite – это инструмент для создания модифицированных сборок Windows. Она позволят вырезать из дистрибутива определённый функционал, отключать системные службы, задавать определённые системные настройки, внедрять драйверы, обновления, твики реестра, сторонние программы. Она не является способом создания сборок с предустановленным сторонним софтом, как, например, подготовка Windows к развёртыванию в режиме аудита. Но NTLite – это мощнейший твикер дистрибутива с возможностью применения инструмента Post-Install для автоматического запуска процесса установки добавленных в такой дистрибутив сторонних программ.

NTLite - платная программа, перед покупкой лицензии можно опробовать её триал-версию на сайте

https://www.ntlite.com

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

Распаковка исходника

Первым делом подготовим исходный ISO-образ с процессом установки Windows 7, 8.1 или 10. Либо монтируем ISO-файл для отображения в проводнике.

А затем копируем всё содержимое установочного диска в отдельную рабочую папку.

Либо извлекаем содержимое ISO с помощью архиватора. Кому как удобнее.

Добавление исходника

Запускаем программу NTLite. В её окне жмём «Добавить» и указываем путь к рабочей папке, куда мы скопировали (или распаковали) на предыдущем этапе содержимое ISO-исходника.

Увидим структуру компонентов этого ISO, в числе которых будут редакции той или иной версии Windows. Нам нужно выбрать одну из них. Все проделанные в дальнейшем настройки теперь будут касаться только выбранной редакции, и только она одна будет содержаться в модифицированном дистрибутиве, который мы получим по итогу проделанной работы. Выбираем редакцию, вызываем на ней контекстное меню, жмём «Загрузить». Если мы работаем с дистрибутивом Windows 8.1 и 10, нужно ещё дополнительно подтвердить операцию конвертирования образа из формата WIM в ESD.

NTLite проводит операции с WIM-образами – файлами install.wim, в которых содержатся установочные файлы Windows. И ESD-образы – сжатые файлы install.esd, в которых хранится дистрибутив версий системы 8.1 и 10 – программа в процессе загрузки будет преобразовывать в WIM-формат. Конвертирование образов из ESD в WIM – процедура небыстрая, придётся подождать. С образами Windows 7 в этом плане намного проще, поскольку они изначально существуют в WIM-формате. Так что, друзья, знакомство с возможностями NTLite лучше начать с создания модифицированных сборок «Семёрки». В таком случае не придётся конвертировать образ ни изначально из WIM в ESD, ни наоборот по завершении подготовки сборки для её упаковки в ISO.

  • Примечание : в процессе конвертирования образа из ESD в WIM на слабых и усреднённых компьютерах может подгружаться процессор. В таком случае можно на время отключить защиту в реальном времени Защитника Windows или стороннего антивируса.

Когда WIM- или ESD-образ загрузится в окно программы NTLite, увидим сообщение об этом возле выбранной редакции. Также обнаружим, что на панели слева, кроме текущей вертикальной вкладки «Исходник», появилась масса других вкладок. Исследуем их по очереди. Переходим на вкладку «Компоненты».

Компоненты, функции и службы Windows

Во вкладке «Компоненты» можно отключать, соответственно, те или иные компоненты системы, снимая их галочки. Что здесь можно отключить? Аппаратную поддержку отдельных периферийных устройств типа модемов, ИК- и Bluetooth-модулей, смарт-карт и т.п., а также драйверы комплектующих, которые точно не будут подключены к тому ПК или ноутбуку, для которого готовится сборка. Также можно отключить такие компоненты как:

Языки и раскладки клавиатуры;

DVD-проигрыватель и мастер записи оптических дисков;

Утилиты «Ножницы», «Заметки», «Диктофон», «Запись действий»;

Распознавание речи, экранную клавиатуру;

Штатный Skype;

Сетевые компоненты;

Центр мобильности;

Защитник Windows;

Если стоит задача уменьшить вес самого дистрибутива, можно ориентироваться на отображаемый в последнем столбце таблицы вес компонентов. Компоненты Windows – это тот её функционал, который вырезается, а не отключается. Не все вырезанные из дистрибутива компоненты можно будет потом беспроблемно скачать в Интернете и внедрить в систему. Так что, проводя настройки во вкладке «Компоненты», нужно очень аккуратно обращаться со снятием галочек.

Во вкладке ниже «Функции» подобраны функции Windows, которые не вырезаются, но они могут быть отключены в дистрибутиве по умолчанию. Или, наоборот, включены, тогда как в официальном образе от Microsoft отключены. Как, например, NET Framework 3.5 или службы IIS. Из числа предустановленных функций отключить можно, если не будут использоваться:

Гаджеты Windows 7;

Штатные офисные игры («Косынка», «Паук», «Солитер» и т.п.);

Windows Media Center, проигрыватель Windows Media, DVD-студию, компоненты планшетного ПК;

Подсистему Linux;

Службы XPS и PDF-принтер;

Индексацию и внутрисистемный поиск;

  • Примечание : NTLite может предложить даже отключение Internet Explorer, однако делать этого не стоит. Отключение Internet Explorer может вызвать сбой в работе других приложений системы.

Чтобы отключить ту или иную функцию, необходимо убрать её галочку. Чтобы включить, галочку нужно установить.

Вкладка «Службы» позволяет отключить неиспользуемые службы Windows. Или, наоборот, включить те, что отключены по умолчанию. Для выбранной службы из выпадающего перечня в конце строки необходимо выбрать нужное значение, например, «Отключено».

Службы Windows – ещё один важный этап настройки дистрибутива, где нужно не переборщить с отключением. Без автозапуска определённых служб Windows может попросту не запустится. Тут нужно также чётко понимать, что и зачем мы отключаем.

Настройки

Во вкладке «Локальный компьютер» собраны некоторые системные настройки типа задания параметров файла подкачки, UAC, Центра обновлений и т.п. Задаются настройки либо выставлением положения «Включено/Отключено», либо указанием конкретных данных, как в случае с файлом подкачки.

Вкладка «Пользователи» - нечто лёгкого твикера для тонкой настройки юзабилити системы.

Обновления, драйверы, твики реестра

Во вкладке «Обновления» можем просмотреть перечень уже интегрированных в исходный дистрибутив обновлений, а также добавить новые пакеты обновлений.

Вкладка «Драйверы» служит для добавления, соответственно, драйверов. Нажав кнопку «Добавить», сможем указать программе NTLite папку с подборкой драйверов для конкретного устройства. Или, например, интегрировать в процесс установки Windows 7 универсальные драйверы USB 3.0.

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

Если у нас есть какие-то твики системного реестра - REG-файлы с теми или иными настройками, можем и их внести в состав дистрибутива. И эти твики будут применены на этапе предварительной настройки системы вместе с установкой драйверов. В нашем случае, например, добавлен REG-файл смены метода масштабирования Windows 10 на тот, что был в версии 8.1.

Персонификация

Во вкладке «Автоматическая», если сборка делается для себя, можно установить некоторые персональные настройки как то:

Язык, часовой пояс;

Имя компьютера, ключ активации;

Настройки сети;

И тогда эти этапы установки пройдут автоматически. Эти настройки задаются выбором нужного значения в выпадающем списке или установкой положения «Истина/Ложь».

Установка сторонних программ

Вкладка «После установки» - это настройка функции Post-Install, череды автоматически запускающихся процессов инсталляции стороннего ПО. Внедрение софта в сборку Windows хоть в виде уже установленных программ, хоть в виде Post-Install - спорное улучшение, если мы говорим о компьютерах обычных пользователей. Версии программ быстро устаревают, и такие доработки, естественно, увеличивают вес дистрибутива. Тем не менее несколько программ-завсегдатаев типа браузера, архиватора, файлового менеджера внедрить можно. Функция Post-Install, реализованная программой NTLite, запускается на завершающем этапе предварительной настройки Windows. И на этом этапе - без интерфейса системы, без активности лишних служб и драйверов - установка программ проходит очень быстро.

  • Примечание : друзья, если по причине внедрения стороннего софта ISO-образ установки Windows выйдет более 4 Гб, записать его на флешку для компьютеров с BIOS UEFI, которая должна быть отформатирована в FAT32, поможет утилита WinSetupFromUSB. Она предусматривает механизм обхода ограничений FAT32.

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

Когда все настройки будут произведены, можем жать внизу «Применить».

Упаковка модифицированной сборки в образ

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

И только когда программа NTLite завершит конвертирование образа из WIM в ESD, запускаем создание ISO.

Тестирование

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




Top