C 计算FAT16中文件的字节偏移量需要什么?

C 计算FAT16中文件的字节偏移量需要什么?,c,fat16,C,Fat16,我有一个程序和FAT16图像。方便的是,映像从引导扇区开始。从那里我提取了根目录、每个扇区的字节数和每个集群的字节数 从根目录获取子目录的字节偏移量的算法,将名为path的给定子文件夹的r设置为从image[0]到子目录项的字节偏移量,如下所示: // non-C formatted externally defined values image = open_some_fat16_image() path = the_name_of_a_directory_whose_

我有一个程序和FAT16图像。方便的是,映像从引导扇区开始。从那里我提取了根目录、每个扇区的字节数和每个集群的字节数

从根目录获取子目录的字节偏移量的算法,将名为
path
的给定子文件夹的
r
设置为从
image[0]
到子目录项的字节偏移量,如下所示:

    // non-C formatted externally defined values
    image = open_some_fat16_image()
    path = the_name_of_a_directory_whose_parent_is_root()
    LEN_DIR_NAME = 2
    LEN_DIRECTORY_ENTRY = 32
    FREE_ENTRY_MARKER = 0xE5
    END_OF_DIR_MARKER = 0
    OFFSET_DIR_ATTR = 11
    FLAG_DIRECTORY = 0x10
    OFFSET_FIRST_CLUSTER = 26
    current_dir = byte_loc_root;

    unsigned long r = 0;
    for ( int i = 0; i < ( *fat_fs ).root_entry_count && r == 0; i++ )
    {
        // get the name
        char dir_name[ LEN_DIR_NAME +1 ];
        unsigned long byte_loc_dir_name = current_dir + ( i * LEN_DIRECTORY_ENTRY );
        lseek( image, byte_loc_dir_name, SEEK_SET );
        read( image, dir_name, LEN_DIR_NAME );
        dir_name[ LEN_DIR_NAME ] = '\0';

        // is valid entry
        if ( FREE_ENTRY_MARKER == ( unsigned char ) dir_name[ 0 ] ) { continue; }
        if ( END_OF_DIR_MARKER == ( unsigned char ) dir_name[ 0 ] ) { break; }

        // no right whitespace
        for ( int i = 0; i < LEN_DIR_NAME; i ++ )
        {
            if ( ! isspace( dir_name[ i ] ) ) { continue; }
            dir_name[ i ] = '\0';
        }

        // is a match
        if ( 0 != strcmp( dir_name, path ) ) { continue; }

        // is a directory
        unsigned long byte_loc_dir_attr = byte_loc_dir_name + OFFSET_DIR_ATTR;
        lseek( image, byte_loc_dir_attr, SEEK_SET );
        uint8_t attr;
        read( image, &attr, 1 );
        if ( FLAG_DIRECTORY != attr ) { continue; }

        // get cluster
        unsigned long byte_loc_dir_first_cluster = byte_loc_dir_name + OFFSET_FIRST_CLUSTER;
        lseek( image, byte_loc_dir_first_cluster, SEEK_SET );
        uint16_t cluster_idx;
        read( image, & cluster_idx, LEN_FIRST_CLUSTER );

        r = cluster_idx * ( *fat_fs ).sectors_per_cluster * ( *fat_fs ).bytes_per_sector;
    }
//非C格式的外部定义值
image=open\u some\u fat16\u image()
path=其父目录为根目录的目录的名称
LEN_DIR_NAME=2
LEN_目录_条目=32
自由输入标记=0xE5
_DIR_标记的结束\u=0
偏移量\u方向\u属性=11
FLAG_DIRECTORY=0x10
偏移量\u第一个\u簇=26
当前地址=字节地址根;
无符号长r=0;
对于(int i=0;i<(*fat\u fs).root\u entry\u count&&r==0;i++)
{
//得到名字
char dir_name[LEN_dir_name+1];
无符号长字节\u loc\u dir\u name=当前\u dir+(i*LEN\u目录项);
lseek(图像,字节位置方向名称,搜索集);
读取(图像、目录名称、镜头目录名称);
目录名[LEN_dir_name]='\0';
//是否为有效条目
if(FREE_ENTRY_MARKER==(unsigned char)dir_name[0]){continue;}
if(END_OF_DIR_MARKER==(unsigned char)DIR_name[0]){break;}
//没有正确的空格
for(int i=0;i
我已运行此程序并已验证
-
每个集群的扇区数(==4)和
-每个扇区的字节数(==512)
匹配图像中的值(通过十六进制编辑器)。我还验证了
cluster\u idx
与图像中的内容匹配(通过hex\u编辑器+FAT16浏览器)

r=cluster\u idx*sectors\u per\u cluster*bytes\u per\u sector=960*4*512
设置为is:0x1E0000。使用FAT16浏览器,我能够在我给出的subdirectory参数中找到文件。现在获得了其中一个文件名,我使用hex_编辑器在图像中查找它。子目录列表的位置为:0x1ED200


我很确定我已经正确地获得了所有的值,除了
r
。我不确定采用哪些值来获取
r
关闭的缺少的53760字节。设置
r
的方式是否缺少某些内容?

您应该在引导扇区内发送BPB转储。看到和

对于FAT 16,磁盘的布局通常如下所示:

boot sector
fat 1
fat 2
root dir
cluster 2
cluster 3
...
因此,您需要调整:

RootDirSectors = <round up (32 bytes * 
                           BPB.RootDirectoryEntries) to be a multiple of BPB.BytesPerSector> / BPB.BytesPerSector

Cluster2SectorNumber = 
    BPB.ReservedSectors 
     + BPB.NumberOfFats * BPB.SectorsPerFat
     + RootDirSectors

ClusterSectorNumber = 
    Cluster2SectorNumber
     + (cluster_idx - 2) * BPB.SectorsPerCluster

ClusterByteNumber =
    ClusterSectorNumber * BPB.BytesPerSector
RootDirSectors=/BPB.BytesPerSector
Cluster2SectorNumber=
保留部门
+BPB.NumberOfFats*BPB.SectorsPerFat
+根目录扇区
ClusterSectorNumber=
群集2扇区号
+(集群_idx-2)*BPB.SectorsPerCluster
丛生丛生数=
ClusterSectorNumber*BPB.BytesPerSector

这似乎是一个很好的完整参考:步骤1:确保I/O函数的返回值,如
lseek();read()
和预期的一样。@MarkRansom是的,我主要是根据那个页面和微软的白皮书构建程序的。页面显示目录条目中的“第一个集群”指向该条目在擦除后所占用的第一个集群。当我去那里的时候,除了零什么都没有,它离子目录的实际位置很远,53760 B。在所讨论的文件的根目录条目中,文件的起始集群是
960
?有趣。0x1ED200不是群集边界(0x1ED000是)。