mirror of
https://github.com/Tolik-Trek/FORMAT.git
synced 2026-06-15 17:31:40 +03:00
...
This commit is contained in:
parent
e881028ea0
commit
192559b49a
BIN
FAT table calculate.pdf
Normal file
BIN
FAT table calculate.pdf
Normal file
Binary file not shown.
BIN
Format FAT.docx
BIN
Format FAT.docx
Binary file not shown.
BIN
Format FAT.pdf
Normal file
BIN
Format FAT.pdf
Normal file
Binary file not shown.
@ -1 +1 @@
|
|||||||
Subproject commit a26f6ad2cf2eab977cab8baa0c83b0c2a91a5e53
|
Subproject commit b9c54c9a1e027b35fba71efa26378a555cfd75db
|
||||||
143
Tmp2.md
Normal file
143
Tmp2.md
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
Вот подробный алгоритм и формулы для программы низкоуровневого форматирования в FAT. Это не просто вызов стандартных утилит, а именно создание структуры разделов "с нуля".
|
||||||
|
|
||||||
|
Общий порядок действий (Алгоритм)
|
||||||
|
|
||||||
|
Определение параметров носителя и выбор FAT:
|
||||||
|
|
||||||
|
Получить общий размер диска/раздела в секторах (total_sectors).
|
||||||
|
Получить размер сектора (обычно 512, 1024, 2048, 4096 байт). bytes_per_sector.
|
||||||
|
Ключевое решение: На основе total_sectors * bytes_per_sector выбрать тип FAT (12/16/32). Используй пороговые значения (см. ниже).
|
||||||
|
Вычисление основных геометрических параметров:
|
||||||
|
|
||||||
|
Рассчитать sectors_per_cluster. Это степень двойки (1, 2, 4, 8, ... 64). Зависит от размера тома.
|
||||||
|
Определить размер зарезервированной области (reserved_sectors), обычно 1 для дисков, больше для разделов. Для FAT32 минимум 32.
|
||||||
|
Определить количество копий FAT (num_fats). Обычно 2.
|
||||||
|
Рассчитать размер одной таблицы FAT (sectors_per_fat). Самый сложный расчет, зависит от всего.
|
||||||
|
Создание загрузочной записи (BPB - Bios Parameter Block):
|
||||||
|
|
||||||
|
Заполнить структуру BPB (для FAT12/16) или BPB32 (для FAT32) вычисленными значениями.
|
||||||
|
Для FAT32 дополнительно вычислить и заполнить структуру FSInfo.
|
||||||
|
Запись структур на диск:
|
||||||
|
|
||||||
|
Сектор 0: Записать MBR с таблицей разделов (если форматируем весь диск, а не раздел).
|
||||||
|
Первый сектор раздела (Logical Sector 0):
|
||||||
|
|
||||||
|
Записать BPB (и возможно, загрузочный код).
|
||||||
|
Для FAT32: записать FSInfo (обычно в сектор 1) и Backup Boot Sector (обычно в сектор 6).
|
||||||
|
Зарезервированная область: Пропустить reserved_sectors.
|
||||||
|
Таблицы FAT: Записать num_fats копий FAT, каждая размером sectors_per_fat.
|
||||||
|
|
||||||
|
Инициализировать первые кластеры:
|
||||||
|
|
||||||
|
FAT[0] = 0xF?? | media_type (например, 0xF8 для HDD).
|
||||||
|
FAT[1] = 0xFFF / 0xFFFF / 0x0FFFFFFF (конец цепочки).
|
||||||
|
Область данных: Заполнить корневой каталог (для FAT12/16) нулями. Для FAT32 корневой каталог находится в кластере 2.
|
||||||
|
Формулы и детали для каждой FAT
|
||||||
|
|
||||||
|
1. Выбор FAT (Пороговые значения)
|
||||||
|
|
||||||
|
FAT12: До 4084 кластеров в области данных. (Макс. объем зависит от размера кластера, но обычно до ~32 МБ).
|
||||||
|
FAT16: От 4085 до 65524 кластеров. (Обычно от ~32 МБ до ~2 ГБ с 32-килобайтными кластерами. Теоретически до 4 ГБ с 64К кластерами, но не поддерживается многими ОС).
|
||||||
|
FAT32: От 65525 кластеров и более. (От ~512 МБ до 2 ТБ. Официально до 32 ГБ в Windows, но работает и больше).
|
||||||
|
Важно: Это кластеры, а не байты!
|
||||||
|
|
||||||
|
2. Ключевые вычисляемые параметры
|
||||||
|
|
||||||
|
Общие переменные:
|
||||||
|
|
||||||
|
total_sectors - общее число секторов раздела.
|
||||||
|
bytes_per_sector - 512, 1024, 2048, 4096.
|
||||||
|
sectors_per_cluster (spc) - степень двойки. Подбирается для оптимального количества кластеров.
|
||||||
|
reserved_sectors (rsvd_sec_cnt) - обычно 1 (FAT12/16) или 32 (FAT32).
|
||||||
|
num_fats - почти всегда 2.
|
||||||
|
root_dir_entries (root_ent_cnt) - только для FAT12/16. Обычно 512 (для дискет 224). Для FAT32 = 0.
|
||||||
|
sectors_per_fat (fat_sz32 для FAT32) - самый важный и сложный параметр.
|
||||||
|
Алгоритм расчета sectors_per_fat (итеративный или прямой)
|
||||||
|
|
||||||
|
Для FAT12/16:
|
||||||
|
|
||||||
|
Рассчитать размер корневого каталога в секторах:
|
||||||
|
root_dir_sectors = ((root_dir_entries * 32) + (bytes_per_sector - 1)) / bytes_per_sector
|
||||||
|
Рассчитать размер области данных в секторах:
|
||||||
|
data_sectors = total_sectors - (reserved_sectors + (num_fats * fat_sz) + root_dir_sectors)
|
||||||
|
Здесь fat_sz (искомое) пока неизвестно.
|
||||||
|
Рассчитать общее число кластеров:
|
||||||
|
total_clusters = data_sectors / sectors_per_cluster
|
||||||
|
Теперь можно найти нужный размер FAT:
|
||||||
|
|
||||||
|
Для FAT16: Каждая запись FAT - 2 байта. fat_sz = (total_clusters * 2 + (bytes_per_sector - 1)) / bytes_per_sector
|
||||||
|
Для FAT12: Каждая запись - 1.5 байта. fat_sz = (total_clusters * 3 + 1) / (2 * bytes_per_sector) (с округлением вверх).
|
||||||
|
Но fat_sz влияет на data_sectors. Это цикл. На практике используют итерацию или таблицы. Простой способ:
|
||||||
|
|
||||||
|
Сначала грубо оцени data_sectors = total_sectors - reserved_sectors - root_dir_sectors.
|
||||||
|
Посчитай total_clusters, затем fat_sz.
|
||||||
|
Уточни data_sectors, вычтя num_fats * fat_sz.
|
||||||
|
Пересчитай total_clusters. Если изменился сильно - повтори.
|
||||||
|
Для FAT32:
|
||||||
|
|
||||||
|
Формула проще, т.к. корневой каталог в области данных.
|
||||||
|
data_sectors = total_sectors - reserved_sectors - (num_fats * fat_sz32)
|
||||||
|
total_clusters = data_sectors / sectors_per_cluster
|
||||||
|
Размер записи FAT32 - 4 байта. Поэтому:
|
||||||
|
fat_sz32 = (total_clusters * 4 + (bytes_per_sector - 1)) / bytes_per_sector
|
||||||
|
Опять цикл. Стартовое приближение: fat_sz32 = 0. Повторять расчет, пока fat_sz32 не стабилизируется (обычно 2-3 итерации).
|
||||||
|
Структуры данных (Упрощенно)
|
||||||
|
|
||||||
|
Общая структура BPB (смещения для сектора 512 байт):
|
||||||
|
0x00: JMP инструкция (3 байта)
|
||||||
|
0x03: OEM Name (8 байт)
|
||||||
|
0x0B: bytes_per_sector (WORD)
|
||||||
|
0x0D: sectors_per_cluster (BYTE)
|
||||||
|
0x0E: reserved_sectors (WORD)
|
||||||
|
0x10: num_fats (BYTE)
|
||||||
|
0x11: root_ent_cnt (WORD) ; 0 для FAT32
|
||||||
|
0x13: total_sectors_16 (WORD) ; если 0, см. 0x20
|
||||||
|
0x15: media (BYTE) ; 0xF8 для HDD
|
||||||
|
0x16: fat_sz_16 (WORD) ; 0 для FAT32
|
||||||
|
0x18: sectors_per_track (WORD)
|
||||||
|
0x1A: num_heads (WORD)
|
||||||
|
0x1C: hidden_sectors (DWORD) ; важно для разделов
|
||||||
|
0x20: total_sectors_32 (DWORD)
|
||||||
|
|
||||||
|
Дополнение для FAT12/16 (Extended BPB):
|
||||||
|
0x24: drive_number (BYTE)
|
||||||
|
0x25: reserved (BYTE)
|
||||||
|
0x26: boot_sig (BYTE) ; 0x29
|
||||||
|
0x27: volume_id (DWORD)
|
||||||
|
0x2B: volume_label (11 BYTE)
|
||||||
|
0x36: file_system_type (8 BYTE) ; "FAT12 ", "FAT16 "
|
||||||
|
0x3E: boot_code (448 BYTE)
|
||||||
|
0x1FE: signature (WORD) ; 0xAA55
|
||||||
|
|
||||||
|
Дополнение для FAT32 (Extended BPB):
|
||||||
|
0x24: fat_sz_32 (DWORD) ; sectors_per_fat
|
||||||
|
0x28: ext_flags (WORD)
|
||||||
|
0x2A: fs_version (WORD) ; 0
|
||||||
|
0x2C: root_cluster (DWORD) ; обычно 2
|
||||||
|
0x30: fs_info_sector (WORD) ; обычно 1
|
||||||
|
0x32: backup_boot_sector (WORD) ; обычно 6
|
||||||
|
0x34: reserved[12] (12 BYTE)
|
||||||
|
... (поля drive_number, boot_sig, volume_id, label, type аналогичны, но смещения другие)
|
||||||
|
0x1FE: signature (WORD) ; 0xAA55
|
||||||
|
|
||||||
|
Порядок записи для FAT32 (особое внимание!)
|
||||||
|
Сектор 0: Основная загрузочная запись (BPB32).
|
||||||
|
Сектор 1: Структура FSInfo (опционально, но рекомендуется).
|
||||||
|
Сектор 6: Резервная копия загрузочного сектора (Backup Boot Sector). Должна быть идентична сектору 0.
|
||||||
|
Сектор 7 и далее: Зарезервированная область.
|
||||||
|
FAT1: Начинается с сектора reserved_sectors (обычно 32).
|
||||||
|
FAT2: Начинается с сектора reserved_sectors + fat_sz32.
|
||||||
|
Область данных: Начинается с сектора reserved_sectors + num_fats * fat_sz32.
|
||||||
|
|
||||||
|
Кластер 2: Является началом корневого каталога (значение root_cluster в BPB).
|
||||||
|
На что обратить особое внимание
|
||||||
|
|
||||||
|
Выравнивание: Для производительности на современных SSD резервируй reserved_sectors так, чтобы FAT и данные начинались с границ больших блоков (например, 1 МБ).
|
||||||
|
Размер кластера: Большой кластер уменьшает размер FAT и ускоряет работу с большими файлами, но ведет к потере места на мелких файлах. Выбирай по таблицам Microsoft.
|
||||||
|
FAT32 и большие диски: При размерах >32 ГБ многие ОС (старые Windows) откажутся монтировать том. Это ограничение на уровне ОС, а не файловой системы.
|
||||||
|
hidden_sectors: Критически важный параметр при форматировании раздела, а не всего диска. Это смещение раздела от начала диска в секторах. Если установить неверно, диск не загрузится или данные будут потеряны.
|
||||||
|
Зеркалирование FAT: В FAT32 есть флаг ext_flags, который может отключать зеркалирование FAT (копию). По умолчанию зеркалирование включено, и FAT1 и FAT2 должны быть идентичны.
|
||||||
|
Тестирование: Всегда тестируй алгоритм на виртуальных дисках (файлах-образах) перед работой с реальными носителями. Используй hexdump или дисковые редакторы для проверки структур.
|
||||||
|
Рекомендация: Изучи исходный код утилит mkfs.fat (из пакета dosfstools в Linux) или fatformat. Там реализованы все эти алгоритмы с учетом множества крайних случаев.
|
||||||
|
|
||||||
|
Продолжить с DeepSeek
|
||||||
@ -802,12 +802,12 @@ BOOT_SECTOR EQU #00
|
|||||||
.JMP EQU #00 ; BLOCK 3,0 BS_jmpBoot Jump to bootstrap (E.g. eb 3c 90; on i86: JMP 003E NOP. One finds either eb xx 90, or e9 xx xx.
|
.JMP EQU #00 ; BLOCK 3,0 BS_jmpBoot Jump to bootstrap (E.g. eb 3c 90; on i86: JMP 003E NOP. One finds either eb xx 90, or e9 xx xx.
|
||||||
.ID_NAME EQU #03 ; TEXT 8 BS_OEMName DOS NAME - DB "DSS_1.70"
|
.ID_NAME EQU #03 ; TEXT 8 BS_OEMName DOS NAME - DB "DSS_1.70"
|
||||||
; Block Parameters BIOS
|
; Block Parameters BIOS
|
||||||
.BytesPerSector DRV_GET_PAR (IX) EQU #0B ; WORD #200 BPB_BytsPerSec <09> §¬¥à ᥪâ®à ¢ ¡ ©â å
|
.BytesPerSector GenIOCTL.GetParams EQU #0B ; WORD #200 BPB_BytsPerSec <09> §¬¥à ᥪâ®à ¢ ¡ ©â å
|
||||||
.SectorsPerCluster ;!TODO EQU #0D ; BYTE 2 BPB_SecPerClus <09> §¬¥à ª« áâ¥à ¢ ᥪâ®à å
|
.SectorsPerCluster ;!TODO EQU #0D ; BYTE 2 BPB_SecPerClus <09> §¬¥à ª« áâ¥à ¢ ᥪâ®à å
|
||||||
.RESERVED_SECTORS !RESERVED_SECTORS EQU #0E ; WORD 1 BPB_ResvdSecCnt <09> §¬¥à á¨á⥬®© ®¡« á⨠(¢ª«îç ï íâ®â ᥪâ®à) RESERVE SECTORS
|
.RESERVED_SECTORS !RESERVED_SECTORS EQU #0E ; WORD 1 BPB_ResvdSecCnt <09> §¬¥à á¨á⥬®© ®¡« á⨠(¢ª«îç ï íâ®â ᥪâ®à) RESERVE SECTORS
|
||||||
.Number_of_FATs ;!TODO EQU #10 ; BYTE 2 BPB_NumFATs Š®«¨ç¥á⢮ â ¡«¨æ FAT
|
.Number_of_FATs 2 EQU #10 ; BYTE 2 BPB_NumFATs Š®«¨ç¥á⢮ â ¡«¨æ FAT
|
||||||
.FilesInRootDIR 0 EQU #11 ; WORD 112 BPB_RootEntCnt —¨á«® ®¯¨á ⥫¥© ä ©«®¢ ¢ ª®à¥¢®¬ ª â «®£¥ (¢ FAT32 - 0)
|
.FilesInRootDIR 0 EQU #11 ; WORD 112 BPB_RootEntCnt —¨á«® ®¯¨á ⥫¥© ä ©«®¢ ¢ ª®à¥¢®¬ ª â «®£¥ (¢ FAT32 - 0)
|
||||||
.SectorsPerDrive ;!TODO EQU #13 ; WORD 1440 BPB_TotSec16 ޡ饥 ç¨á«® ᥪâ®à®¢ ¤¨áª¥ (¥á«¨ 0, â® à §¬¥à - ¢ .BPB_BIG_TOTAL_SECTORS)
|
.SectorsPerDrive 0 EQU #13 ; WORD 1440 BPB_TotSec16 ޡ饥 ç¨á«® ᥪâ®à®¢ ¤¨áª¥ (¥á«¨ 0, â® à §¬¥à - ¢ .BPB_BIG_TOTAL_SECTORS)
|
||||||
.DRIVE_TYPE !DRV_TYPE EQU #15 ; BYTE #F0 BPB_Media ’¨¯ ãáâனáâ¢
|
.DRIVE_TYPE !DRV_TYPE EQU #15 ; BYTE #F0 BPB_Media ’¨¯ ãáâனáâ¢
|
||||||
.SectorsPerFAT16 0 EQU #16 ; WORD 2 BPB_FATSz16 <09> §¬¥à ®¤®© FAT ¢ ᥪâ®à å (0 ¢ FAT32)
|
.SectorsPerFAT16 0 EQU #16 ; WORD 2 BPB_FATSz16 <09> §¬¥à ®¤®© FAT ¢ ᥪâ®à å (0 ¢ FAT32)
|
||||||
.SectorsPerTrack GenIOCTL.GetParams EQU #18 ; WORD 9 BPB_SecPerTrk <09> §¬¥à ¤®à®¦ª¨ ¢ ᥪâ®à å
|
.SectorsPerTrack GenIOCTL.GetParams EQU #18 ; WORD 9 BPB_SecPerTrk <09> §¬¥à ¤®à®¦ª¨ ¢ ᥪâ®à å
|
||||||
@ -817,14 +817,14 @@ BOOT_SECTOR EQU #00
|
|||||||
.BPB_BIG_TOTAL_SECTORS_H EQU #22 ; WORD 0 BPB_TotSec32 BIG TOTAL SECTOR High word
|
.BPB_BIG_TOTAL_SECTORS_H EQU #22 ; WORD 0 BPB_TotSec32 BIG TOTAL SECTOR High word
|
||||||
; FAT 32
|
; FAT 32
|
||||||
.SectorsPerFAT32 EQU #24 ; DWORD 4 BPB_FATSz32 <09> §¬¥à ®¤®© FAT ¢ ᥪâ®à å
|
.SectorsPerFAT32 EQU #24 ; DWORD 4 BPB_FATSz32 <09> §¬¥à ®¤®© FAT ¢ ᥪâ®à å
|
||||||
.MainFATnumber EQU #28 ; WORD 0 BPB_ExtFlags <09>®¬¥à £« ¢®© â ¡«¨æë FAT
|
.MainFATnumber 0 EQU #28 ; WORD 0 BPB_ExtFlags <09>®¬¥à £« ¢®© â ¡«¨æë FAT
|
||||||
.Version EQU #2A ; WORD 0 BPB_FSVer ‚¥àá¨ï FAT32 (®¡ëç® 0)
|
.Version 0 EQU #2A ; WORD 0 BPB_FSVer ‚¥àá¨ï FAT32 (®¡ëç® 0)
|
||||||
.RootDirStartCluster EQU #2C ; DWORD 2 BPB_RootClus <09>¥à¢ë© ª« áâ¥à ª®à¥¢®£® ª â «®£ (®¡ëç® 2)
|
.RootDirStartCluster 2 EQU #2C ; DWORD 2 BPB_RootClus <09>¥à¢ë© ª« áâ¥à ª®à¥¢®£® ª â «®£ (®¡ëç® 2)
|
||||||
.FSINFO_Sector EQU #30 ; WORD 1 BPB_FSInfo <09>®¬¥à ᥪâ®à áâàãªâãàë FSINFO (®¡ëç® 1)
|
.FSINFO_Sector 1 EQU #30 ; WORD 1 BPB_FSInfo <09>®¬¥à ᥪâ®à áâàãªâãàë FSINFO (®¡ëç® 1)
|
||||||
.CopyBootSector EQU #32 ; WORD 6 BPB_BkBootSec <09>®¬¥à ᥪâ®à - ª®¯¨¨ § £à㧮箣® (®¡ëç® 6)
|
.CopyBootSector 6 EQU #32 ; WORD 6 BPB_BkBootSec <09>®¬¥à ᥪâ®à - ª®¯¨¨ § £à㧮箣® (®¡ëç® 6)
|
||||||
.reserved_block: EQU #34 ; BLOCK 12 BPB_Reserved ‡ १¥à¢¨à®¢ ®
|
.reserved_block: 0 EQU #34 ; BLOCK 12 BPB_Reserved ‡ १¥à¢¨à®¢ ®
|
||||||
.FDD_Number EQU #40 ; BYTE 0 BS_DrvNum <09>®¬¥à ¤¨áª®¢®¤ ¤«ï äãªæ¨© BIOS
|
.FDD_Number GenIOCTL.GetParams&#F0 EQU #40 ; BYTE 0 BS_DrvNum <09>®¬¥à ¤¨áª®¢®¤ ¤«ï äãªæ¨© BIOS
|
||||||
.reserved_2: EQU #41 ; BYTE 0 BS_Reserved1 ‡ १¥à¢¨à®¢ ®
|
.reserved_2: 0 EQU #41 ; BYTE 0 BS_Reserved1 ‡ १¥à¢¨à®¢ ®
|
||||||
.FAT32.EXT_BOOT_REC_SIGNATURE EQU #42 ; BYTE #29 BS_BootSig ‘¨£ âãà - #29
|
.FAT32.EXT_BOOT_REC_SIGNATURE EQU #42 ; BYTE #29 BS_BootSig ‘¨£ âãà - #29
|
||||||
.FAT32.SERIAL_NUMBER EQU #43 ; DWORD 0 BS_VolID VOLUME SERIAL NUMBER
|
.FAT32.SERIAL_NUMBER EQU #43 ; DWORD 0 BS_VolID VOLUME SERIAL NUMBER
|
||||||
.FAT32.LABEL EQU #47 ; TEXT 11 BS_VolLab Œ¥âª ¤¨áª
|
.FAT32.LABEL EQU #47 ; TEXT 11 BS_VolLab Œ¥âª ¤¨áª
|
||||||
@ -844,7 +844,45 @@ BOOT_SECTOR EQU #00
|
|||||||
.FAT12_FDD EQU 1
|
.FAT12_FDD EQU 1
|
||||||
.FAT12_HDD
|
.FAT12_HDD
|
||||||
.FAT16_HDD
|
.FAT16_HDD
|
||||||
.FAT32_HDD EQU
|
.FAT32_HDD EQU 32
|
||||||
|
|
||||||
|
CALCULATED_FAT_PARAMETERS:
|
||||||
|
.FAT_TYPE BYTE TABLES.FAT12 ; [x]
|
||||||
|
.BytesPerSector: WORD #200 ; predefined ; [x]
|
||||||
|
.SectorsPerCluster: BYTE 32 ; predefined ; [x]
|
||||||
|
.RESERVED_SECTORS: WORD 0 ; [x]
|
||||||
|
.Number_of_FATs: BYTE 2 ; predefined ;
|
||||||
|
.FilesInRootDIR: WORD 0 ; FAT32 constant ; [ ] FAT ; [x] FAT32
|
||||||
|
.SectorsPerDrive: WORD 0 ; FAT32 constant ; [x] +-
|
||||||
|
.DRIVE_TYPE: WORD 0 ; ;
|
||||||
|
.SectorsPerFAT16: WORD 0 ; FAT32 constant ;
|
||||||
|
.HEADS WORD 0 ;
|
||||||
|
.HIDDEN WORD 0 ; ®â ç « MBR, extMBR ;
|
||||||
|
.BPB_BIG_TOTAL_SECTORS_L WORD 0 ; [x] +-
|
||||||
|
.BPB_BIG_TOTAL_SECTORS_H WORD 0 ; [x] +-
|
||||||
|
; FAT 12, FAT 16
|
||||||
|
.BPB_PHISICAL_DRIVE_NUMBER BYTE #80 ; [x]
|
||||||
|
.reserved_1 BYTE 0 ;
|
||||||
|
.FAT.EXT_BOOT_REC_SIGNATURE BYTE #29 ;
|
||||||
|
.FAT.SERIAL_NUMBER DWORD 0 ;
|
||||||
|
.FAT.LABEL TEXT 11 ;
|
||||||
|
.ID_FAT TEXT 8 ;
|
||||||
|
; FAT32
|
||||||
|
.SectorsPerFAT32 DWORD 0 ;
|
||||||
|
.MainFATnumber WORD 0 ; BPB_ExtFlags ;
|
||||||
|
.Version WORD 0 ; constant ;
|
||||||
|
.RootDirStartCluster DWORD 2 ;
|
||||||
|
.FSINFO_Sector WORD 1 ; constant ;
|
||||||
|
.CopyBootSector WORD 6 ; constant ;
|
||||||
|
.reserved_block: BLOCK 12 ; constant ;
|
||||||
|
.FDD_Number BYTE 0 ;
|
||||||
|
.reserved_2: BYTE 0 ; constant ;
|
||||||
|
.FAT32.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ;
|
||||||
|
.FAT32.SERIAL_NUMBER DWORD 0 ;
|
||||||
|
.FAT32.LABEL TEXT 11 ;
|
||||||
|
.ID_FAT32 TEXT 8 ; constant ;
|
||||||
|
; #5A ;
|
||||||
|
|
||||||
|
|
||||||
¤«ï ᬥ饨ï FAT ¤® ªà ⮣® 4096 § 票ï:
|
¤«ï ᬥ饨ï FAT ¤® ªà ⮣® 4096 § 票ï:
|
||||||
1) tmp1 = ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10
|
1) tmp1 = ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10
|
||||||
@ -853,8 +891,179 @@ BOOT_SECTOR EQU #00
|
|||||||
4) error = (tmp3 >= #1000'0000) ; LBA28
|
4) error = (tmp3 >= #1000'0000) ; LBA28
|
||||||
reserved_sectors = ( ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10) - .HIDDEN
|
reserved_sectors = ( ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10) - .HIDDEN
|
||||||
;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
FORMAT_FAT32:
|
||||||
|
; Ž¯à¥¤¥«¥¨¥ ¯ à ¬¥â஢ ®á¨â¥«ï ¨ ¢ë¡®à FAT
|
||||||
|
.STEP1: ; íâ ¤®«¦ ¡ëâì ®¡é¥© ¤«ï § ¯®«¥¨ï £¥®¬¥âਨ ¤¨áª
|
||||||
|
LD A,VARIABLES.CurrentDrive
|
||||||
|
LD BC,Dss.DRV.GenIOCTL.GetParams
|
||||||
|
RST ToDSS.DRV
|
||||||
|
;
|
||||||
|
;!TODO CHECK ERROR
|
||||||
|
;
|
||||||
|
EX AF,AF'
|
||||||
|
AND #F0
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER),A
|
||||||
|
; !FIXIT ¢ ਠ⠤«ï ¢¨â
|
||||||
|
LD A,H
|
||||||
|
OR L
|
||||||
|
JR NZ,.BPB_BIG_TOTAL_SECTORS
|
||||||
|
;
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.SectorsPerDrive),DE
|
||||||
|
;!TODO ãáâ ®¢¨âì ä« £, çâ® ¬¥«ª¨© ¤¨áª ¥ ¤«ï FAT32 ¯à¨ €¢â®¬ â¥
|
||||||
|
JR .STEP1_2
|
||||||
|
;
|
||||||
|
.BPB_BIG_TOTAL_SECTORS:
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_L),DE
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H),HL
|
||||||
|
.STEP1_2: ; à §¬¥à ᥪâ®à
|
||||||
|
XOR A
|
||||||
|
SRL B
|
||||||
|
RRA
|
||||||
|
LD C,A
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.BytesPerSector),BC
|
||||||
|
; à §¬¥à ¤¨áª ¢ ¡ ©â å
|
||||||
|
CALL MUL32_POWER2
|
||||||
|
LD (VOLUME_SIZE_BYTES),DE
|
||||||
|
LD (VOLUME_SIZE_BYTES + 2),HL
|
||||||
|
LD (VOLUME_SIZE_BYTES + 4),A
|
||||||
|
LD E,H
|
||||||
|
LD D,A
|
||||||
|
CALL AUTO_CHOOSE_FAT_PARAMS
|
||||||
|
;!FIXIT
|
||||||
|
; RET C
|
||||||
|
;
|
||||||
|
LD A,C
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.FAT_TYPE),A
|
||||||
|
CP TABLES.FAT32
|
||||||
|
LD A,(RESERVED_SECTORS.FAT32)
|
||||||
|
JR Z,.set_reserved_s
|
||||||
|
;
|
||||||
|
LD A,(RESERVED_SECTORS.FAT)
|
||||||
|
.set_reserved_s:
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.RESERVED_SECTORS),A
|
||||||
|
LD HL,(CALCULATED_FAT_PARAMETERS.BytesPerSector)
|
||||||
|
DEC HL
|
||||||
|
SBC HL,DE
|
||||||
|
LD HL,(CALCULATED_FAT_PARAMETERS.BytesPerSector)
|
||||||
|
EX DE,HL
|
||||||
|
JR C,.BPS_OK
|
||||||
|
; á«ãç ©, ¥á«¨ â ¡«¨çë© ª« áâ¥à ¬¥ìè¥ á¥ªâ®à
|
||||||
|
LD A,1
|
||||||
|
.BPS_OK: CALL C,DIV16_POWER2
|
||||||
|
;!FIXIT
|
||||||
|
; RET C
|
||||||
|
;
|
||||||
|
LD (CALCULATED_FAT_PARAMETERS.SectorsPerCluster),A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; -> DE - 4 ¨ 5 ¡ ©âë à §¬¥à à §¤¥« .
|
||||||
|
; ¤®«¦® ¡ëâì ãáâ ®¢«¥® § 票¥ VOLUME_SIZE_BYTES.
|
||||||
|
; <- DE - CLUSTER SIZE.
|
||||||
|
; C - FAT TYPE.
|
||||||
|
AUTO_CHOOSE_FAT_PARAMS:
|
||||||
|
LD IX,TABLES.FAT_TYPES
|
||||||
|
LD A,TABLES.FAT_TYPES.Records
|
||||||
|
LD BC,TABLES.FAT_TYPES.LineSize
|
||||||
|
.loop: LD L,(IX)
|
||||||
|
LD H,(IX+1)
|
||||||
|
SBC HL,DE
|
||||||
|
JR C,.found
|
||||||
|
;
|
||||||
|
ADD IX,BC
|
||||||
|
DEC A
|
||||||
|
JR NZ,.loop
|
||||||
|
; ã á FAT12 c ª« áâ¥à®¬ ¢ 512
|
||||||
|
; ¤® ¯à®¢¥à¨âì à §¤¥« ¬¨¨¬ «ìë© à §¬¥à ¤«ï FAT
|
||||||
|
; sec_bpb + sec_fat + sec_root_dir + sec_for_data
|
||||||
|
LD A,D
|
||||||
|
OR E
|
||||||
|
JR NZ,.found
|
||||||
|
;
|
||||||
|
LD HL,(VOLUME_SIZE_BYTES + 1)
|
||||||
|
LD DE,8
|
||||||
|
SBC HL,DE
|
||||||
|
RET C ; à §¤¥« ᫨誮¬ ¬ « ¤«ï FAT12 (<2048)
|
||||||
|
.found: ; ¤®áâ ñ¬ ¯ à ¬¥âàë ¨§ â ¡«¨æë
|
||||||
|
DI
|
||||||
|
LD (.restore_SP),SP
|
||||||
|
LD SP,IX
|
||||||
|
POP HL ; 宫®á⮥
|
||||||
|
POP DE ; CLUSTER SIZE
|
||||||
|
POP BC ; C - FAT TYPE
|
||||||
|
LD A,C
|
||||||
|
.restore_SP+1: LD SP,0
|
||||||
|
EI
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
; -> HLDE * BC. BC = á⥯¥ì ¤¢®©ª¨
|
||||||
|
; <- AHLDE
|
||||||
|
; CF=1 - error
|
||||||
|
MUL32_POWER2: XOR A
|
||||||
|
.loop: EX DE,HL
|
||||||
|
ADD HL,HL
|
||||||
|
EX DE,HL
|
||||||
|
ADC HL,HL
|
||||||
|
ADC A,0
|
||||||
|
RET C
|
||||||
|
;
|
||||||
|
SRL B
|
||||||
|
RR C
|
||||||
|
JR NC,.loop
|
||||||
|
;
|
||||||
|
EX DE,HL
|
||||||
|
AND A
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
; -> HL / DE. DE = á⥯¥ì ¤¢®©ª¨
|
||||||
|
; <- A = HL / DE
|
||||||
|
; CF=1 - error
|
||||||
|
DIV16_POWER2: XOR A
|
||||||
|
.loop: INC A
|
||||||
|
SBC HL,DE
|
||||||
|
JR NC,.loop
|
||||||
|
DEC A
|
||||||
|
RET Z ; error: ¤¥«¨¬®¥ < ¤¥«¨â¥«ï
|
||||||
|
CCF
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MACRO FAT_TYPES_LINE (vol_size, clu_size, fat_type)
|
||||||
|
WORD vol_size, clu_size : BYTE fat_type
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
MODULE TABLES
|
||||||
|
FAT12 EQU 0
|
||||||
|
FAT16 EQU 1
|
||||||
|
FAT32 EQU 2
|
||||||
|
; VOL SIZE CLUSTER SIZE FAT TYPE
|
||||||
|
FAT_TYPES: FAT_TYPES_LINE (#0800, 32768, FAT32) ; > 32768
|
||||||
|
FAT_TYPES_LINE (#0400, 16384, FAT32) ; 16384..32768 Mb
|
||||||
|
FAT_TYPES_LINE (#0200, 8192, FAT32) ; 8192..16384 Mb
|
||||||
|
FAT_TYPES_LINE (#0100, 4096, FAT32) ; 4096..8192 Mb
|
||||||
|
FAT_TYPES_LINE (#0080, 32768, FAT16) ; 2048..4096 Mb
|
||||||
|
FAT_TYPES_LINE (#0040, 16384, FAT16) ; 1023..2048 Mb
|
||||||
|
FAT_TYPES_LINE (#0020, 8192, FAT16) ; 511..1023 Mb
|
||||||
|
FAT_TYPES_LINE (#0010, 4096, FAT16) ; 256..511 Mb
|
||||||
|
FAT_TYPES_LINE (#0008, 2048, FAT16) ; 128..256 Mb
|
||||||
|
FAT_TYPES_LINE (#0004, 1024, FAT16) ; 64..128 Mb
|
||||||
|
FAT_TYPES_LINE (#0002, 512, FAT16) ; 32..64 Mb
|
||||||
|
; ¥á«¨ ¬¥ìè¥, â® FAT12
|
||||||
|
.LineSize EQU 5
|
||||||
|
.Records EQU ($ - .FAT_TYPES)/.LineSize
|
||||||
|
ENDMODULE
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
ENDIF
|
ENDIF
|
||||||
306
tmp1.c
Normal file
306
tmp1.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
#include "../include/fttf.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct {
|
||||||
|
BYTE jmpBoot[3];
|
||||||
|
BYTE OEMName[8];
|
||||||
|
WORD bytesPerSector;
|
||||||
|
BYTE sectorsPerCluster;
|
||||||
|
WORD reservedSectorCount;
|
||||||
|
BYTE numFATs;
|
||||||
|
WORD rootEntryCount;
|
||||||
|
WORD totalSectors16;
|
||||||
|
BYTE media;
|
||||||
|
WORD FATSize16;
|
||||||
|
WORD sectorsPerTrack;
|
||||||
|
WORD numberHeads;
|
||||||
|
DWORD hiddenSectors;
|
||||||
|
DWORD totalSectors32;
|
||||||
|
DWORD FATSize32;
|
||||||
|
WORD extFlags;
|
||||||
|
WORD FSVersion;
|
||||||
|
DWORD rootCluster;
|
||||||
|
WORD FSInfoSector;
|
||||||
|
WORD backupBootSector;
|
||||||
|
BYTE reserved[12];
|
||||||
|
BYTE driveNumber;
|
||||||
|
BYTE reserved1;
|
||||||
|
BYTE bootSignature;
|
||||||
|
DWORD volumeID;
|
||||||
|
BYTE volumeLabel[11];
|
||||||
|
BYTE fileSystemType[8];
|
||||||
|
} FAT32BootSector;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DWORD leadSignature;
|
||||||
|
BYTE reserved1[480];
|
||||||
|
DWORD structSignature;
|
||||||
|
DWORD freeCount;
|
||||||
|
DWORD nextFree;
|
||||||
|
BYTE reserved2[12];
|
||||||
|
DWORD trailSignature;
|
||||||
|
} FSInfoSector;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
BOOL FormatDrive(WCHAR driveLetter, HWND hwnd) {
|
||||||
|
WCHAR volumePath[MAX_PATH];
|
||||||
|
swprintf(volumePath, MAX_PATH, L"\\\\.\\%c:", driveLetter);
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Opening drive %c:...\r\n", driveLetter);
|
||||||
|
|
||||||
|
HANDLE hDrive = CreateFileW(
|
||||||
|
volumePath,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||||
|
LogMessage(hwnd, L"Failed to open drive (error %lu)\r\n", GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Locking volume...\r\n");
|
||||||
|
if (!LockVolume(hDrive)) {
|
||||||
|
LogMessage(hwnd, L"Failed to lock volume\r\n");
|
||||||
|
CloseHandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Dismounting volume...\r\n");
|
||||||
|
if (!DismountVolume(hDrive)) {
|
||||||
|
LogMessage(hwnd, L"Warning: Could not dismount volume\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DISK_GEOMETRY diskGeometry;
|
||||||
|
DWORD bytesReturned;
|
||||||
|
|
||||||
|
if (!DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||||
|
&diskGeometry, sizeof(diskGeometry), &bytesReturned, NULL)) {
|
||||||
|
LogMessage(hwnd, L"Failed to get disk geometry\r\n");
|
||||||
|
CloseHandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONGLONG diskSize = (ULONGLONG)diskGeometry.Cylinders.QuadPart *
|
||||||
|
diskGeometry.TracksPerCylinder *
|
||||||
|
diskGeometry.SectorsPerTrack *
|
||||||
|
diskGeometry.BytesPerSector;
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Disk size: %.2f GB\r\n", (double)diskSize / (1024.0 * 1024.0 * 1024.0));
|
||||||
|
LogMessage(hwnd, L"Bytes per sector: %lu\r\n", diskGeometry.BytesPerSector);
|
||||||
|
|
||||||
|
FAT32Params params;
|
||||||
|
if (!CalculateFAT32Parameters(diskSize, diskGeometry.BytesPerSector, ¶ms)) {
|
||||||
|
LogMessage(hwnd, L"Couldn't calculate FAT32 params\r\n");
|
||||||
|
CloseHandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Sectors per cluster: %lu\r\n", params.sectorsPerCluster);
|
||||||
|
LogMessage(hwnd, L"Total sectors: %lu\r\n", params.totalSectors);
|
||||||
|
LogMessage(hwnd, L"Sectors per FAT: %lu\r\n", params.sectorsPerFAT);
|
||||||
|
|
||||||
|
if (!WriteFAT32Structures(hDrive, ¶ms, hwnd)) {
|
||||||
|
LogMessage(hwnd, L"Failed to write FAT32 structures\r\n");
|
||||||
|
CloseHandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hDrive);
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Refreshing drive...\r\n");
|
||||||
|
WCHAR driveRoot[4] = {driveLetter, L':', L'\\', 0};
|
||||||
|
SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, driveRoot, NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CalculateFAT32Parameters(ULONGLONG diskSize, DWORD bytesPerSector, FAT32Params* params) {
|
||||||
|
params->bytesPerSector = bytesPerSector;
|
||||||
|
params->totalSectors = (DWORD)(diskSize / bytesPerSector);
|
||||||
|
params->reservedSectors = 32;
|
||||||
|
params->numberOfFATs = 2;
|
||||||
|
params->rootDirFirstCluster = 2;
|
||||||
|
|
||||||
|
if (diskSize < 512ULL * 1024 * 1024) {
|
||||||
|
params->sectorsPerCluster = 1;
|
||||||
|
} else if (diskSize < 8ULL * 1024 * 1024 * 1024) {
|
||||||
|
params->sectorsPerCluster = 8;
|
||||||
|
} else if (diskSize < 16ULL * 1024 * 1024 * 1024) {
|
||||||
|
params->sectorsPerCluster = 16;
|
||||||
|
} else if (diskSize < 32ULL * 1024 * 1024 * 1024) {
|
||||||
|
params->sectorsPerCluster = 32;
|
||||||
|
} else {
|
||||||
|
params->sectorsPerCluster = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD tmpVal1 = params->totalSectors - params->reservedSectors;
|
||||||
|
DWORD tmpVal2 = (256 * params->sectorsPerCluster) + params->numberOfFATs;
|
||||||
|
tmpVal2 = tmpVal2 / 2;
|
||||||
|
params->sectorsPerFAT = (tmpVal1 + tmpVal2 - 1) / tmpVal2;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WriteFAT32Structures(HANDLE hDrive, FAT32Params* params, HWND hwnd) {
|
||||||
|
LARGE_INTEGER pos;
|
||||||
|
pos.QuadPart = 0;
|
||||||
|
if (!SetFilePointerEx(hDrive, pos, NULL, FILE_BEGIN)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Writing boot sector...\r\n");
|
||||||
|
|
||||||
|
FAT32BootSector bootSector;
|
||||||
|
memset(&bootSector, 0, sizeof(bootSector));
|
||||||
|
|
||||||
|
bootSector.jmpBoot[0] = 0xEB;
|
||||||
|
bootSector.jmpBoot[1] = 0x58;
|
||||||
|
bootSector.jmpBoot[2] = 0x90;
|
||||||
|
|
||||||
|
memcpy(bootSector.OEMName, "MSWIN4.1", 8);
|
||||||
|
bootSector.bytesPerSector = (WORD)params->bytesPerSector;
|
||||||
|
bootSector.sectorsPerCluster = (BYTE)params->sectorsPerCluster;
|
||||||
|
bootSector.reservedSectorCount = (WORD)params->reservedSectors;
|
||||||
|
bootSector.numFATs = params->numberOfFATs;
|
||||||
|
bootSector.rootEntryCount = 0;
|
||||||
|
bootSector.totalSectors16 = 0;
|
||||||
|
bootSector.media = 0xF8;
|
||||||
|
bootSector.FATSize16 = 0;
|
||||||
|
bootSector.sectorsPerTrack = 63;
|
||||||
|
bootSector.numberHeads = 255;
|
||||||
|
bootSector.hiddenSectors = 0;
|
||||||
|
bootSector.totalSectors32 = params->totalSectors;
|
||||||
|
bootSector.FATSize32 = params->sectorsPerFAT;
|
||||||
|
bootSector.extFlags = 0;
|
||||||
|
bootSector.FSVersion = 0;
|
||||||
|
bootSector.rootCluster = params->rootDirFirstCluster;
|
||||||
|
bootSector.FSInfoSector = 1;
|
||||||
|
bootSector.backupBootSector = 6;
|
||||||
|
bootSector.driveNumber = 0x80;
|
||||||
|
bootSector.bootSignature = 0x29;
|
||||||
|
bootSector.volumeID = GetTickCount();
|
||||||
|
memcpy(bootSector.volumeLabel, "NO NAME ", 11);
|
||||||
|
memcpy(bootSector.fileSystemType, "FAT32 ", 8);
|
||||||
|
|
||||||
|
BYTE* sector = (BYTE*)malloc(params->bytesPerSector);
|
||||||
|
if (!sector) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
memcpy(sector, &bootSector, sizeof(bootSector));
|
||||||
|
sector[510] = 0x55;
|
||||||
|
sector[511] = 0xAA;
|
||||||
|
|
||||||
|
DWORD written;
|
||||||
|
if (!WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL)) {
|
||||||
|
free(sector);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Writing FSInfo sector...\r\n");
|
||||||
|
|
||||||
|
FSInfoSector fsInfo;
|
||||||
|
memset(&fsInfo, 0, sizeof(fsInfo));
|
||||||
|
fsInfo.leadSignature = 0x41615252;
|
||||||
|
fsInfo.structSignature = 0x61417272;
|
||||||
|
fsInfo.freeCount = 0xFFFFFFFF;
|
||||||
|
fsInfo.nextFree = 0xFFFFFFFF;
|
||||||
|
fsInfo.trailSignature = 0xAA550000;
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
memcpy(sector, &fsInfo, sizeof(fsInfo));
|
||||||
|
|
||||||
|
if (!WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL)) {
|
||||||
|
free(sector);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.QuadPart = 2 * params->bytesPerSector;
|
||||||
|
SetFilePointerEx(hDrive, pos, NULL, FILE_BEGIN);
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Writing backup boot sector...\r\n");
|
||||||
|
|
||||||
|
pos.QuadPart = 6 * params->bytesPerSector;
|
||||||
|
SetFilePointerEx(hDrive, pos, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
memcpy(sector, &bootSector, sizeof(bootSector));
|
||||||
|
sector[510] = 0x55;
|
||||||
|
sector[511] = 0xAA;
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
memcpy(sector, &fsInfo, sizeof(fsInfo));
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Writing FAT tables...\r\n");
|
||||||
|
|
||||||
|
pos.QuadPart = params->reservedSectors * params->bytesPerSector;
|
||||||
|
SetFilePointerEx(hDrive, pos, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
for (int fat = 0; fat < params->numberOfFATs; fat++) {
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
|
||||||
|
DWORD* fatEntries = (DWORD*)sector;
|
||||||
|
fatEntries[0] = 0x0FFFFFF8;
|
||||||
|
fatEntries[1] = 0x0FFFFFFF;
|
||||||
|
fatEntries[2] = 0x0FFFFFFF;
|
||||||
|
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
for (DWORD i = 1; i < params->sectorsPerFAT; i++) {
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(hwnd, L"Clearing root directory...\r\n");
|
||||||
|
|
||||||
|
DWORD rootDirSector = params->reservedSectors +
|
||||||
|
(params->numberOfFATs * params->sectorsPerFAT) +
|
||||||
|
((params->rootDirFirstCluster - 2) * params->sectorsPerCluster);
|
||||||
|
|
||||||
|
pos.QuadPart = rootDirSector * params->bytesPerSector;
|
||||||
|
SetFilePointerEx(hDrive, pos, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
memset(sector, 0, params->bytesPerSector);
|
||||||
|
for (DWORD i = 0; i < params->sectorsPerCluster; i++) {
|
||||||
|
WriteFile(hDrive, sector, params->bytesPerSector, &written, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sector);
|
||||||
|
|
||||||
|
FlushFileBuffers(hDrive);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LockVolume(HANDLE hDrive) {
|
||||||
|
DWORD bytesReturned;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
if (DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
Sleep(500);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL UnmountVolume(HANDLE hDrive) {
|
||||||
|
DWORD bytesReturned;
|
||||||
|
return DeviceIoControl(hDrive, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DismountVolume(HANDLE hDrive) {
|
||||||
|
return UnmountVolume(hDrive);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user