45 if (cluster >
fs->data_clusters + 1) {
46 die(
"Internal error: cluster out of range in get_fat() (%lu > %lu).",
47 (
unsigned long)cluster, (
unsigned long)(
fs->data_clusters + 1));
50 switch (
fs->fat_bits) {
52 ptr = &((
unsigned char *)
fat)[cluster * 3 / 2];
53 entry->value = 0xfff & (cluster & 1 ? (
ptr[0] >> 4) | (
ptr[1] << 4) :
57 entry->value = le16toh(((
unsigned short *)
fat)[cluster]);
64 entry->value =
e & 0xfffffff;
69 die(
"Bad FAT entry size: %d bits.",
fs->fat_bits);
83 int eff_size, alloc_size;
86 int first_ok, second_ok;
92 if (
fs->cluster_owner)
97 total_num_clusters =
fs->data_clusters + 2;
98 eff_size = (total_num_clusters *
fs->fat_bits + 7) / 8ULL;
100 if (
fs->fat_bits != 12)
101 alloc_size = eff_size;
105 alloc_size = (total_num_clusters * 12 + 23) / 24 * 3;
110 second =
alloc(alloc_size);
111 fs_read(
fs->fat_start +
fs->fat_size, eff_size, second);
113 if (second &&
memcmp(
first, second, eff_size) != 0) {
119 if (first_ok && !second_ok) {
120 printf(
"FATs differ - using first FAT.\n");
123 if (!first_ok && second_ok) {
124 printf(
"FATs differ - using second FAT.\n");
128 if (first_ok && second_ok) {
130 printf(
"FATs differ but appear to be intact. Use which FAT ?\n"
131 "1) Use first FAT\n2) Use second FAT\n");
132 if (
get_key(
"12",
"?") ==
'1') {
139 printf(
"FATs differ but appear to be intact. Using first "
144 if (!first_ok && !second_ok) {
145 printf(
"Both FATs appear to be corrupt. Giving up.\n");
152 fs->fat = (
unsigned char *)
first;
158 for (
i = 2;
i <
fs->data_clusters + 2;
i++) {
161 if (curEntry.
value == 1) {
162 printf(
"Cluster %ld out of range (1). Setting to EOF.\n",
166 if (curEntry.
value >=
fs->data_clusters + 2 &&
168 printf(
"Cluster %ld out of range (%ld > %ld). Setting to EOF.\n",
169 (
long)(
i - 2), (
long)curEntry.
value,
170 (
long)(
fs->data_clusters + 2 - 1));
195 if (cluster >
fs->data_clusters + 1) {
196 die(
"Internal error: cluster out of range in set_fat() (%lu > %lu).",
197 (
unsigned long)cluster, (
unsigned long)(
fs->data_clusters + 1));
202 else if ((
long)
new == -2)
204 else if (
new >
fs->data_clusters + 1) {
205 die(
"Internal error: new cluster out of range in set_fat() (%lu > %lu).",
206 (
unsigned long)
new, (
unsigned long)(
fs->data_clusters + 1));
209 switch (
fs->fat_bits) {
211 data =
fs->fat + cluster * 3 / 2;
212 offs =
fs->fat_start + cluster * 3 / 2;
216 data[0] = ((
new & 0xf) << 4) | (prevEntry.
value >> 8);
220 if (cluster !=
fs->data_clusters + 1)
223 subseqEntry.
value = 0;
224 data[0] =
new & 0xff;
225 data[1] = (
new >> 8) | ((0xff & subseqEntry.
value) << 4);
230 data =
fs->fat + cluster * 2;
231 offs =
fs->fat_start + cluster * 2;
240 data =
fs->fat + cluster * 4;
241 offs =
fs->fat_start + cluster * 4;
250 die(
"Bad FAT entry size: %d bits.",
fs->fat_bits);
285 die(
"Internal error: next_cluster on bad cluster");
305 if (
fs->cluster_owner ==
NULL)
306 die(
"Internal error: attempt to set owner in non-existent table");
308 if (owner &&
fs->cluster_owner[cluster]
309 && (
fs->cluster_owner[cluster] != owner))
310 die(
"Internal error: attempt to change file owner");
311 fs->cluster_owner[cluster] = owner;
316 if (
fs->cluster_owner ==
NULL)
319 return fs->cluster_owner[cluster];
327 printf(
"Checking for bad clusters.\n");
328 for (
i = 2;
i <
fs->data_clusters + 2;
i++) {
334 printf(
"Cluster %lu is unreadable.\n", (
unsigned long)
i);
346 printf(
"Checking for unused clusters.\n");
348 for (
i = 2;
i <
fs->data_clusters + 2;
i++) {
363 printf(
"Reclaimed %d unused cluster%s (%llu bytes).\n", (
int)reclaimed,
364 reclaimed == 1 ?
"" :
"s",
365 (
unsigned long long)reclaimed *
fs->cluster_size);
384 if (start_cluster == 0)
387 for (
i = start_cluster;
i <
fs->data_clusters + 2;
i++) {
429 int reclaimed, files;
436 printf(
"Reclaiming unconnected clusters.\n");
438 total_num_clusters =
fs->data_clusters + 2;
446 for (
i = 2;
i < total_num_clusters;
i++) {
475 for (
i = 2;
i < total_num_clusters;
i++) {
481 if (!num_refs[curEntry.
value]--)
482 die(
"Internal error: num_refs going below zero");
484 changed = curEntry.
value;
485 printf(
"Broke cycle at cluster %lu in free chain.\n", (
unsigned long)
i);
490 if (num_refs[curEntry.
value] == 0)
501 files = reclaimed = 0;
502 for (
i = 2;
i < total_num_clusters;
i++)
510 if (
fs->fat_bits == 32)
512 for (walk =
i; walk > 0 && walk != -1;
514 de.size =
htole32(le32toh(de.size) +
fs->cluster_size);
520 printf(
"Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
521 reclaimed, reclaimed == 1 ?
"" :
"s",
522 (
unsigned long long)reclaimed *
fs->cluster_size, files,
523 files == 1 ?
"" :
"s");
537 for (
i = 2;
i <
fs->data_clusters + 2;
i++) {
545 if (!
fs->fsinfo_start)
549 printf(
"Checking free cluster summary.\n");
550 if (
fs->free_clusters != 0xFFFFFFFF) {
551 if (
free !=
fs->free_clusters) {
552 printf(
"Free cluster summary wrong (%ld vs. really %ld)\n",
553 (
long)
fs->free_clusters, (
long)
free);
555 printf(
"1) Correct\n2) Don't correct\n");
560 printf(
" Auto-correcting.\n");
569 printf(
"Free cluster summary uninitialized (should be %ld)\n", (
long)
free);
572 printf(
"1) Set it\n2) Leave it uninitialized\n");
574 printf(
" Auto-setting.\n");
584 sizeof(le_free), &le_free);
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
#define FAT_IS_BAD(fs, v)
#define FAT_IS_EOF(fs, v)
off_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern, int gen_name)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static unsigned char * fat
#define memcpy(s1, s2, n)
static unsigned __int64 next
#define offsetof(TYPE, MEMBER)
char get_key(const char *valid, const char *prompt)
void reclaim_free(DOS_FS *fs)
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
DOS_FILE * get_owner(DOS_FS *fs, uint32_t cluster)
int bad_cluster(DOS_FS *fs, uint32_t cluster)
uint32_t update_free(DOS_FS *fs)
void read_fat(DOS_FS *fs)
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
static void tag_free(DOS_FS *fs, DOS_FILE *owner, uint32_t *num_refs, uint32_t start_cluster)
void get_fat(FAT_ENTRY *entry, void *fat, uint32_t cluster, DOS_FS *fs)
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
void reclaim_file(DOS_FS *fs)
int fs_test(off_t pos, int size)
void fs_read(off_t pos, int size, void *data)
void fs_write(off_t pos, int size, void *data)