aboutsummaryrefslogtreecommitdiffstats
path: root/ldlinux.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldlinux.c')
-rw-r--r--ldlinux.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/ldlinux.c b/ldlinux.c
index 8e697fb..4e4f776 100644
--- a/ldlinux.c
+++ b/ldlinux.c
@@ -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;
}