简体   繁体   English

FAT32实际上不符合Microsoft的文档

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

I'm working on a project in which I need to read the BPB of a FAT32 partition, then based on that, verify that the partition is indeed valid FAT32 before doing anything else with it. 我正在做一个项目,在该项目中,我需要读取FAT32分区的BPB ,然后在此基础上,在对该分区执行任何其他操作之前,请验证该分区确实是有效的FAT32。

According to Microsoft's documentation (in the table starting on page 9), the fields BPB_RootEntCnt (located at 0x17, size 2), and BPB_TotSec16 (located at 0x19, size 2) must both be set to 0 in case of any FAT32 partition. 根据Microsoft的文档 (在第9页开始的表中),对于任何FAT32分区,字段BPB_RootEntCnt (位于0x17,大小2)和BPB_TotSec16 (位于0x19,大小2)都必须都设置为0。 Since the official documentation is very clear about this, I assumed that checking if these are zero is a good idea to verify that the partition is valid FAT32 (these two values are not the only ones I'm using for verification, but these are the problematic ones). 由于官方文档对此非常清楚,因此我认为检查这些值是否为零是验证分区是否为FAT32的好主意(这两个值不是我用于验证的唯一值,但这些是有问题的)。

I tried a number of different storage devices, each formatted to FAT32 under different operating systems, and in every single case, these two fields have non-zero values! 我尝试了许多不同的存储设备,每种存储设备在不同的操作系统下都格式化为FAT32,并且在每种情况下,这两个字段的值都为非零!

Why is this? 为什么是这样? The official documentation of FAT32 clearly states that these fields must be set to zero. FAT32的官方文档明确指出必须将这些字段设置为零。 So how can all the different formatting tools (including Windows' built-in formatting option) ignore this rule? 那么,所有不同的格式化工具(包括Windows的内置格式化选项)如何忽略此规则?

First I thought that my program didn't work as expected, but I think there are no problems with that. 首先,我认为我的程序没有按预期运行,但是我认为这没有问题。 Here's a short, self-contained example, that simply prints out the value of only these two fields of a FAT32 partition: 这是一个简短的独立示例,仅打印出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;
}

This code works on OS X, Linux, and possibly other UNIX-like systems as well, but NOT Windows. 该代码可在OS X,Linux以及可能的其他类似UNIX的系统上运行,但不适用于Windows。 "path to volume" has to be of course /dev/... , for example /dev/disk1s1 on OS X, or /dev/sda1 on Linux. 当然,“卷的路径”必须是/dev/... ,例如OS X上的/dev/disk1s1或Linux上的/dev/sda1

So how can this be? 那怎么可能呢? This program always prints out two non-zero values if you give it the path of a FAT32 partition, while (according to the documentation) these values should be zero. 如果给它提供FAT32分区的路径,该程序将始终打印出两个非零值,而(根据文档)这些值应为零。

It is your program :) 这是你的程序:)
The offsets for BPB_RootEntCnt and BPB_TotSec16 BPB_RootEntCntBPB_TotSec16的偏移量
are not 0x17 (=23) and 0x19 (=25), but 17 and 19 . 不是0x17 (= 23)和0x19 (= 25),而是1719

To compare the data for such issues in the future, it´s helpful to get the first KB 为了将来比较此类问题的数据,获取第一个KB很有帮助
with dd in a file and view it with an hex editor. 在文件中添加dd并使用十六进制编辑器查看。 (and to read more carefully...) (并仔细阅读...)

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

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