diff options
Diffstat (limited to 'ldlinux.c')
-rw-r--r-- | ldlinux.c | 36 |
1 files changed, 29 insertions, 7 deletions
@@ -171,12 +171,31 @@ __u32 nextcluster(__u32 clust_num) __u32 next_cluster; __u32 fat_sector; struct cache_struct *cs; + +#if FATType == FAT12 + int offset; + int lo, hi; +#endif switch(FATType) { case FAT12: fat_sector = (clust_num + clust_num / 2) >> SECTOR_SHIFT; cs = getfatsector(fat_sector); - next_cluster = *(__u16 *)(cs->data + (clust_num*3/2) % 512); + offset = (clust_num * 3 / 2) & ( SECTOR_SIZE -1 ); + if ( offset == 0x1ff ) { + /* + * we got the end of the one fat sector, + * but we don't got we have(just one byte, we need two), + * so store the low part, then read the next fat + * sector, read the high part, then combine it. + */ + lo = *(__u8 *)(cs->data + offset); + cs = getfatsector(fat_sector + 1); + hi = *(__u8 *)cs->data; + next_cluster = (hi << 8) + lo; + } else + next_cluster = *(__u16 *)(cs->data + offset); + if ( clust_num & 0x0001 ) next_cluster >>= 4; /* cluster number is ODD */ else @@ -261,12 +280,13 @@ __u32 nextsector(__u32 sector) * 64K boundaries. * * @param: buf - * @param: curr_sector, the sector where to start reading + * @param: file structure * @param: sectors * */ -void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) +void __getfssec(char *buf, struct open_file_t *file, __u32 sectors) { + __u32 curr_sector = file->file_sector; __u32 frag_start , next_sector; __u32 con_sec_cnt; @@ -301,8 +321,11 @@ void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) if ( !sectors ) break; //curr_sector --; /* this is the last sector actually read */ - curr_sector = next_sector = nextsector(curr_sector); + curr_sector = next_sector; }while( sectors ); + + /* update the file_sector filed for the next read */ + file->file_sector = nextsector(curr_sector); } @@ -329,7 +352,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor if ( sectors > file->file_left ) sectors = file->file_left; - __getfssec(buf, file->file_sector, sectors); + __getfssec(buf, file, sectors); if ( bytes_read >= file->file_bytesleft ) { bytes_read = file->file_bytesleft; @@ -343,8 +366,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor } file->file_left -= sectors; - file->file_sector += sectors; - + return bytes_read; } |