VFAT i_pos value
OGAWA Hirofumi
hirofumi at mail.parknet.co.jp
Sat Dec 3 01:23:56 EST 2011
OGAWA Hirofumi <hirofumi at mail.parknet.co.jp> writes:
> Kai Meyer <kai at gnukai.com> writes:
>
>> Thanks for the helpful response. I'm not entirely sure I understand the
>> next part though. I hacked a dirty entry dumper tool:
>>
>> #include <stdio.h>
>> #include <linux/msdos_fs.h>
>> #include <sys/types.h>
>> #include <sys/stat.h>
>> #include <fcntl.h>
>> #include <unistd.h>
>> #include <string.h>
>>
>> int main(int argc, char** argv)
>> {
>> off_t pos = atoi(argv[2]);
>> unsigned long block;
>> off_t sector;
>> unsigned int offset;
>> int fd = open(argv[1], O_RDONLY);
>> char buf[512];
>> struct msdos_dir_entry dirent;
>> block = pos / (4096 / 32);
>> sector = block * 8;
>> offset = pos % (4096 / 32);
>> printf("block %lu, sector %lu, offset %u\n", block, sector,
>> offset);
>> lseek(fd, sector * 512, SEEK_SET);
>> if (read(fd, buf, 512) < 0) {
>> fprintf(stderr, "Unable to read from device %s\n",
>> argv[1]);
>> return -1;
>> }
>> memcpy(&dirent, buf + offset, sizeof(dirent));
>> printf("name %s\n", dirent.name);
>> printf("attr %u\n", dirent.attr);
>> printf("lcase %u\n", dirent.lcase);
>> printf("ctime_cs %u\n", dirent.ctime_cs);
>> printf("ctime %u\n", dirent.ctime);
>> printf("cdate %u\n", dirent.cdate);
>> printf("adate %u\n", dirent.adate);
>> printf("starthi %u\n", dirent.starthi);
>> printf("time %u\n", dirent.time);
>> printf("date %u\n", dirent.date);
>> printf("start %u\n", dirent.start);
>> printf("size %u\n", dirent.size);
>> }
>>
>> Here's what it outputs:
>>
>> ./vfat_entry /dev/sblsnap0 523793
>> block 4092, sector 32736, offset 17
>> name
>> attr 255
>> lcase 255
>> ctime_cs 255
>> ctime 12799
>> cdate 12670
>> adate 8224
>> starthi 8224
>> time 23072
>> date 21061
>> start 32
>> size 2171155456
>>
>> So, I take starthi, and shift 16 bits left, then and in the start value.
>> That should give me the byte address of the first cluster of the file,
>> correct?
>>
>> Then I need to follow the cluster chain until I get a bad value.
>
> It looks like wrong as dirent. Did you use 523793 really? If so, I think
> 523791 is correct value. :)
And I didn't mention about offset correctly. offset means number of
entries, not bytes offset. So, bytes offset is "buf + offset * 32".
(32 == sizeof(struct msdos_dir_entry))
Thanks.
--
OGAWA Hirofumi <hirofumi at mail.parknet.co.jp>
More information about the Kernelnewbies
mailing list