繁体   English   中英

FAT32实际上不符合Microsoft的文档

[英]FAT32 in practice does not conform Microsoft's documentation

我正在做一个项目,在该项目中,我需要读取FAT32分区的BPB ,然后在此基础上,在对该分区执行任何其他操作之前,请验证该分区确实是有效的FAT32。

根据Microsoft的文档 (在第9页开始的表中),对于任何FAT32分区,字段BPB_RootEntCnt (位于0x17,大小2)和BPB_TotSec16 (位于0x19,大小2)都必须都设置为0。 由于官方文档对此非常清楚,因此我认为检查这些值是否为零是验证分区是否为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/... ,例如OS X上的/dev/disk1s1或Linux上的/dev/sda1

那怎么可能呢? 如果给它提供FAT32分区的路径,该程序将始终打印出两个非零值,而(根据文档)这些值应为零。

这是你的程序:)
BPB_RootEntCntBPB_TotSec16的偏移量
不是0x17 (= 23)和0x19 (= 25),而是1719

为了将来比较此类问题的数据,获取第一个KB很有帮助
在文件中添加dd并使用十六进制编辑器查看。 (并仔细阅读...)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM