Читать, писать и манипулировать FAT32 в C - PullRequest
2 голосов
/ 11 декабря 2011

Я пытаюсь написать программу на C, которая позволяет мне перемещаться по образу файловой системы FAT32. Однако мне трудно понять и применить уравнения для сбора правильных данных. Я использую дистрибутив Linux для Debian, поэтому поддерживается порядок с прямым порядком байтов. Ниже приведен псевдокод с веб-сайта Microsoft о FAT32, вычисляющий следующий кластер для доступа к каталогу или файлу:

    ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
    ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

    FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) =
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) = 
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) | FAT32ClusEntryVal;

Я не совсем понимаю, что делает массив символов SecBuff или к чему он обращается. DWORD должен быть беззнаковым int, и я не уверен, что понимаю и последующие приведения. Любой светлый сарай высоко ценится.

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

1 Ответ

7 голосов
/ 12 декабря 2011

Этот псевдокод предназначен для чтения и записи номера кластера из / в таблицу размещения файлов. Док говорит это прямо между двумя частями псевдокода. Это единственная возможность, если только у вас нет ни малейшего представления о том, как работает FAT12 / 16/32.

------ 8 <------ </p>

Предположим, что это считывается в 8-битный байтовый массив с именем SecBuff. Также предположим, что тип WORD является 16-разрядным без знака, а тип DWORD является 32-разрядным без знака.

If(FATType == FAT16)
    FAT16ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);
Else
    FAT32ClusEntryVal = (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0x0FFFFFFF;

Извлекает содержимое этого кластера. Чтобы установить содержимое этого же кластера, выполните следующие действия:

If(FATType == FAT16)
    *((WORD *) &SecBuff[ThisFATEntOffset]) = FAT16ClusEntryVal;
Else {
     FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) =
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) = 
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) | FAT32ClusEntryVal;
}

------ 8 <------ </p>

Именно эти номера кластеров в ячейках, которыми манипулирует псевдокод выше:

enter image description here

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

SecBuff - массив, содержащий 512-байтовый сектор таблицы размещения файлов. *((DWORD *) приведено во избежание чтения / записи 32-битных значений в отдельных 8-битных фрагментах.

...