FAT32 на практике не соответствует документации Microsoft

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

В соответствии с Документация Microsoft (в таблице, начиная со страницы 9), поля BPB_RootEntCnt (расположен в 0x17, размер 2), и BPB_TotSec16 (расположен в 0x19, размер 2) должен быть установлен в 0 в случае любого раздела FAT32. Поскольку в официальной документации об этом совершенно ясно, я предположил, что проверка, равны ли они нулю, является хорошей идеей, чтобы убедиться, что раздел является допустимым FAT32 (эти два значения не единственные, которые я использую для проверки, но это проблемные).

Я пробовал несколько разных устройств хранения данных, каждое из которых отформатировано в FAT32 в разных операционных системах, и в каждом отдельном случае эти два поля имеют ненулевые значения!

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

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

#include <iostream>
#include <string>
#include <cstdio>
#include <unistd.h>
using namespace std;

void printFAT32Fields(const string& vol) {
// Unmount the volume
system(("sudo umount -f "s + vol + " 1> /dev/null 2>&1"s).c_str());

// Open
auto fp = fopen(vol.c_str(), "r");
if (!fp) {
perror("Error");
throw runtime_error("The volume '"s + vol + "' cannot be accessed!"s);
}
setbuf(fp, NULL);

uint16_t BPB_RootEntCnt = 0x0;
uint16_t BPB_TotSec16   = 0x0;

fseek(fp, 0x17, SEEK_SET);
fread(&BPB_RootEntCnt, 1, 2, fp);

fseek(fp, 0x19, SEEK_SET);
fread(&BPB_TotSec16, 1, 2, fp);

fclose(fp);

cout << BPB_RootEntCnt << " " << BPB_TotSec16 << endl;
}

int main() {

if (getuid()) {
cout << "This program needs root privileges to run!" << endl;
return 0;
}

try {
printFAT32Fields("PATH TO VOLUME GOES HERE");
} catch(runtime_error err) {
cout << err.what();
}

return 0;
}

Этот код работает на OS X, Linux и, возможно, других UNIX-подобных системах, но НЕ на Windows. «путь к объему» должен быть, конечно, /dev/..., например /dev/disk1s1 на OS X или /dev/sda1 в линуксе

Так как это может быть? Эта программа всегда выводит два ненулевых значения, если вы указываете путь к разделу FAT32, в то время как (согласно документации) эти значения должны быть равны нулю.

0

Решение

Это твоя программа 🙂
Смещения для BPB_RootEntCnt а также BPB_TotSec16
не 0x17 (= 23) и 0x19 (= 25), но 17 а также 19,

Чтобы сравнить данные по таким проблемам в будущем, полезно получить первые КБ
с dd в файл и просматривать его с помощью шестнадцатеричного редактора. (и читать внимательнее …)

1

Другие решения


По вопросам рекламы [email protected]