[VFATLIB] Never touch the file system if not in interactive or RW mode.

It's critical not to perform any write on a volume without an exclusive lock on it.
That lock is only acquired if ChkDsk is started in RW mode.
Also added an assert in write routine, to make sure that when we're about to perform
a write operation, we're really allowed to do so.

This will avoid volume corruptions when a simple "chkdsk" is issued from cmd.
To put it simple: check will really check now, and won't attempt any repair.

CORE-14119
This commit is contained in:
Pierre Schweitzer 2017-12-17 13:59:20 +01:00
parent 284a839dbd
commit b0bf7dfb62
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
3 changed files with 137 additions and 117 deletions

View file

@ -350,7 +350,7 @@ void reclaim_free(DOS_FS * fs)
get_fat(&curEntry, fs->fat, i, fs);
if (!get_owner(fs, i) && curEntry.value &&
!FAT_IS_BAD(fs, curEntry.value)) {
!FAT_IS_BAD(fs, curEntry.value) && rw) {
set_fat(fs, i, 0);
reclaimed++;
}
@ -490,30 +490,32 @@ void reclaim_file(DOS_FS * fs)
}
while (changed);
/* Now we can start recovery */
files = reclaimed = 0;
for (i = 2; i < total_num_clusters; i++)
/* If this cluster is the head of an orphan chain... */
if (get_owner(fs, i) == &orphan && !num_refs[i]) {
DIR_ENT de;
off_t offset;
files++;
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC");
de.start = htole16(i & 0xffff);
if (fs->fat_bits == 32)
de.starthi = htole16(i >> 16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs, walk)) {
de.size = htole32(le32toh(de.size) + fs->cluster_size);
reclaimed++;
if (rw) {
/* Now we can start recovery */
files = reclaimed = 0;
for (i = 2; i < total_num_clusters; i++)
/* If this cluster is the head of an orphan chain... */
if (get_owner(fs, i) == &orphan && !num_refs[i]) {
DIR_ENT de;
off_t offset;
files++;
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC");
de.start = htole16(i & 0xffff);
if (fs->fat_bits == 32)
de.starthi = htole16(i >> 16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs, walk)) {
de.size = htole32(le32toh(de.size) + fs->cluster_size);
reclaimed++;
}
fs_write(offset, sizeof(DIR_ENT), &de);
}
fs_write(offset, sizeof(DIR_ENT), &de);
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
reclaimed, reclaimed == 1 ? "" : "s",
(unsigned long long)reclaimed * fs->cluster_size, files,
files == 1 ? "" : "s");
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
reclaimed, reclaimed == 1 ? "" : "s",
(unsigned long long)reclaimed * fs->cluster_size, files,
files == 1 ? "" : "s");
}
free(num_refs);
}
@ -543,9 +545,9 @@ uint32_t update_free(DOS_FS * fs)
(long)fs->free_clusters, (long)free);
if (interactive)
printf("1) Correct\n2) Don't correct\n");
else
else if (rw)
printf(" Auto-correcting.\n");
if (!interactive || get_key("12", "?") == '1')
if ((!interactive && rw) || (interactive && get_key("12", "?") == '1'))
do_set = 1;
}
} else {