1 /* ----------------------------------------------------------------------- *
3 * Copyright 2004 H. Peter Anvin - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
19 #include "libfatint.h"
23 * Convert a cluster number (or 0 for the root directory) to a
24 * sector number. Return -1 on failure.
26 libfat_sector_t
libfat_clustertosector(const struct libfat_filesystem
*fs
,
30 cluster
= fs
->rootcluster
;
34 else if ( cluster
< 2 || cluster
>= fs
->endcluster
)
37 return fs
->data
+ ((libfat_sector_t
)(cluster
-2) << fs
->clustshift
);
41 * Get the next sector of either the root directory or a FAT chain.
42 * Returns 0 on end of file and -1 on error.
45 libfat_sector_t
libfat_nextsector(struct libfat_filesystem
*fs
,
48 int32_t cluster
, nextcluster
;
50 libfat_sector_t fatsect
;
52 uint32_t clustmask
= fs
->clustsize
- 1;
56 if ( s
< fs
->rootdir
)
61 return ( s
< fs
->data
) ? s
: 0;
66 if ( ~rs
& clustmask
)
67 return s
+1; /* Next sector in cluster */
69 cluster
= 2 + (rs
>> fs
->clustshift
);
71 if ( cluster
>= fs
->endcluster
)
74 switch ( fs
->fat_type
) {
77 fatoffset
= cluster
+ (cluster
>> 1);
78 fatsect
= fs
->fat
+ (fatoffset
>> LIBFAT_SECTOR_SHIFT
);
79 fsdata
= libfat_get_sector(fs
, fatsect
);
82 nextcluster
= fsdata
[fatoffset
& LIBFAT_SECTOR_MASK
];
86 fatsect
= fs
->fat
+ (fatoffset
>> LIBFAT_SECTOR_SHIFT
);
87 fsdata
= libfat_get_sector(fs
, fatsect
);
90 nextcluster
|= fsdata
[fatoffset
& LIBFAT_SECTOR_MASK
] << 8;
92 /* Extract the FAT entry */
96 nextcluster
&= 0x0FFF;
98 if ( nextcluster
>= 0x0FF8 )
103 fatoffset
= cluster
<< 1;
104 fatsect
= fs
->fat
+ (fatoffset
>> LIBFAT_SECTOR_SHIFT
);
105 fsdata
= libfat_get_sector(fs
, fatsect
);
108 nextcluster
= read16((le16_t
*)&fsdata
[fatoffset
& LIBFAT_SECTOR_MASK
]);
110 if ( nextcluster
>= 0x0FFF8 )
115 fatoffset
= cluster
<< 2;
116 fatsect
= fs
->fat
+ (fatoffset
>> LIBFAT_SECTOR_SHIFT
);
117 fsdata
= libfat_get_sector(fs
, fatsect
);
120 nextcluster
= read32((le32_t
*)&fsdata
[fatoffset
& LIBFAT_SECTOR_MASK
]);
121 nextcluster
&= 0x0FFFFFFF;
123 if ( nextcluster
>= 0x0FFFFFF8 )
128 return -1; /* WTF? */
131 return libfat_clustertosector(fs
, nextcluster
);