2016-04-08 8 views
2

私はプログラムとFAT16イメージを持っています。好都合なことに、イメージはブートセクタから始まります。そこから、ルートディレクトリ、1セクタあたりのバイト数、1クラスタあたりのバイト数を抽出しました。FAT16のファイルのバイトオフセットを計算するには何が必要ですか?

pathという名前の特定のサブフォルダのためのサブディレクトリエントリにimage[ 0 ]からのバイトオフセットにrを設定し、ルートディレクトリからサブディレクトリのためのバイトオフセットを取得するためのアルゴリズムは、次のとおりです。

// 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; 
    } 

私はしましたこのプログラムを実行して確認したその
- sectors_per_cluster(== 4)、及び
- bytes_per_sector(== 512)
一致(hex_editorを介して)画像の値。また、cluster_idxが画像にあるものと一致することを確認しました(hex_editor + FAT16ブラウザ経由)。

r = cluster_idx * sectors_per_cluster * bytes_per_sector = 960 * 4 * 512は、:0x1E0000に設定されています。 FAT16ブラウザを使用して、私が与えたサブディレクトリ引数でファイルを見つけることができました。これらのファイル名の一つが得られたので、私はhex_editorを使ってイメージ内でそれを探しました。サブディレクトリ一覧の場所は0x1ED200でした。

rを除き、すべての値が正しく取得されていることを確認しています。 rがオフになっている欠落している53760バイトを取得するためにどの値を取るべきかわかりません。 rはどのように設定されていますか?

+0

これは良い完全なリファレンスのように思える:HTTP ://www.maverick-os.dk/FileSystemFormats/FAT16_FileSystem.html –

+0

Step1: 'lseek();のような入出力関数からの戻り値を保証します。 read() 'は期待通りです。 – chux

+0

@ MarkRansomええ、私はそのページとMSのホワイトペーパーから主にプログラムを作りました。このページには、ディレクトリエントリ内の「最初のクラスタ」が、そのエントリが消去された後に占有する最初のクラスタを指していることが示されています。私がそこに行くと、ゼロ以外何もありません、それはサブディレクトリが実際にどこから離れているか、53760 B離れています。 – user2738698

答えて

0

ブートセクタ内のBPBのダンプを送信する必要があります。 FAT 16についてhttps://en.wikipedia.org/wiki/BIOS_parameter_blockhttps://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#BPB

を参照してください、ディスクは通常のようにレイアウトされている:

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 
関連する問題