1 /* ----------------------------------------------------------------------- *
3 * Copyright 2004-2008 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;
61 return (s < fs->data) ? s : 0;
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);
109 read16((le16_t *) & fsdata[fatoffset & LIBFAT_SECTOR_MASK]);
111 if (nextcluster >= 0x0FFF8)
116 fatoffset = cluster << 2;
117 fatsect = fs->fat + (fatoffset >> LIBFAT_SECTOR_SHIFT);
118 fsdata = libfat_get_sector(fs, fatsect);
122 read32((le32_t *) & fsdata[fatoffset & LIBFAT_SECTOR_MASK]);
123 nextcluster &= 0x0FFFFFFF;
125 if (nextcluster >= 0x0FFFFFF8)
130 return -1; /* WTF? */
133 return libfat_clustertosector(fs, nextcluster);