0

According to http://wiki.osdev.org/FAT I'm trying to get the total FAT size. But the result is riddiculus.

What am I doing wrong?

Any help is appreciated! Thank you.

int main(int argc, char *argv[]){
    if(argc == 1){
        printf("Root directory:\n");
    } else {
        char *file_name = argv[1];
        printf("Checking %s...\n", file_name);
        FILE *file = fopen(file_name, "r");
        if (file==NULL) {fputs ("File error\n",stderr); exit (1);}

        unsigned char boot[512];
        fread(boot, 512, 1, file);

        // Sectors per FAT. The size of the FAT in sectors.
        unsigned int sectors_per_fat = (boot[39]<<24)|(boot[38]<<16)|(boot[37]<<8)|boot[36];
        unsigned int fat_count = boot[16];
        unsigned int bytes_per_block = (boot[12]<<8)|boot[11];
        unsigned int total_fat_size = sectors_per_fat*fat_count*bytes_per_block;

        printf("%d\n", total_fat_size);

        /*
        36-4 Sectors per FAT
        16-1 Number of File Allocation Tables.
        11-2 Number of bytes per block (almost always 512).
        */
        fclose(file);

    }

    return 0;
}

the file:

0000000: eb58 906d 6b66 732e 6661 7400 0201 2000  .X.mkfs.fat... .
0000010: 0200 0000 00f8 0000 2000 4000 0000 0000  ........ .@.....
0000020: 400d 0300 0306 0000 0000 0000 0200 0000  @...............
0000030: 0100 0600 0000 0000 0000 0000 0000 0000  ................
0000040: 8000 29c8 a726 5e4e 4f20 4e41 4d45 2020  ..)..&^NO NAME  
0000050: 2020 4641 5433 3220 2020 0e1f be77 7cac    FAT32   ...w|.
0000060: 22c0 740b 56b4 0ebb 0700 cd10 5eeb f032  ".t.V.......^..2
0000070: e4cd 16cd 19eb fe54 6869 7320 6973 206e  .......This is n
0000080: 6f74 2061 2062 6f6f 7461 626c 6520 6469  ot a bootable di
0000090: 736b 2e20 2050 6c65 6173 6520 696e 7365  sk.  Please inse
00000a0: 7274 2061 2062 6f6f 7461 626c 6520 666c  rt a bootable fl
00000b0: 6f70 7079 2061 6e64 0d0a 7072 6573 7320  oppy and..press 
00000c0: 616e 7920 6b65 7920 746f 2074 7279 2061  any key to try a
00000d0: 6761 696e 202e 2e2e 200d 0a00 0000 0000  gain ... .......
00000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.
0000200: 5252 6141 0000 0000 0000 0000 0000 0000  RRaA............
0000210: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000220: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000230: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000240: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000250: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000260: 0000 0000 0000 0000 0000 0000 0000 0000  ................
....

I used these to create the file:

dd if=/dev/zero of=disk.img bs=1k count=100000
losetup /dev/loop0 disk.img
mkdosfs -s 1 -F 32 /dev/loop0 100000
mmswe
  • 707
  • 2
  • 8
  • 20
  • What was the "riddiculus" result? What was expected? – chux - Reinstate Monica May 14 '15 at 16:49
  • Perhaps `unsigned int total_fat_size = sectors_per_fat*fat_count*bytes_per_block;` overflows `unsigned`? – chux - Reinstate Monica May 14 '15 at 16:52
  • I was expecting something below 10,000. It was 1033216 – mmswe May 14 '15 at 16:55
  • Replace `fputs ("File error\n",stderr);` with `perror( file_name );` It is useful to know the reason for the error. – William Pursell May 14 '15 at 16:57
  • Are you sure about endian? If I use little endian I have 0x03060000 * 0x0002 =0x 60C0000. That is 101449728/1024 = 99072 near 100000 blocks you created by dd command. – LPs May 14 '15 at 17:16
  • I'm not sure about anything anymore. – mmswe May 14 '15 at 17:27
  • @LPs: Are you sure with this `0x03060000`? If litle Endian shouldn't it be `0x00000603`? – alk May 14 '15 at 18:03
  • @alk The matter is if byte 36 is the LSB or MSB. – LPs May 14 '15 at 18:06
  • If I read the dump you show I get: 0x603 * 2 * 512 = 1575936 which looks perfectly valid to me. Roughly 15% of the disk is FAT. I wonder where your 1033216 comes from. – alk May 14 '15 at 18:06
  • @LPs: Little endian reads LSB first. Also which `36` are you referring to. I do not see any. – alk May 14 '15 at 18:10
  • @LPS: The byte sequence at offset 36 is `0306 0000` with (for Little Endianness) `03` being the LSB. – alk May 14 '15 at 18:14
  • I have just run your code using an array in memory initialised with the values from your post, in MSVC using your exact calculation method (except my `boot` array only includes the necessary data), and it gives the result `1575936` as commented by @alk. Are you sure this is your exact code that misfires? I notice you didn't check the result of `fread(boot, 512, 1, file);`. What was it? It's crucial to check such things. – Weather Vane May 14 '15 at 18:29
  • 1
    Tiny nitpick: `printf("%u\n", total_fat_size);` for unsigned. – Weather Vane May 14 '15 at 18:34

0 Answers0