diff options
author | Hervé Poussineau <hpoussin@reactos.org> | 2022-10-10 19:55:10 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2022-10-27 20:14:11 +0200 |
commit | d0f95b6ca0241b14d6cc0f366d162684909370a9 (patch) | |
tree | 509f6d78914a96522d5155de4456bdff6ab4ff44 /block | |
parent | 69fbfff95e849156985cf95e2010ffc8762e34e6 (diff) | |
download | qemu-d0f95b6ca0241b14d6cc0f366d162684909370a9.zip qemu-d0f95b6ca0241b14d6cc0f366d162684909370a9.tar.gz qemu-d0f95b6ca0241b14d6cc0f366d162684909370a9.tar.bz2 |
vvfat: allow some writes to bootsector
'reserved1' field in bootsector is used to mark volume dirty, or need to verify.
Allow writes to bootsector which only changes the 'reserved1' field.
This fixes I/O errors on Windows guests.
Resolves: https://bugs.launchpad.net/qemu/+bug/1889421
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Message-Id: <20221010175511.3414357-2-hpoussin@reactos.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/vvfat.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/block/vvfat.c b/block/vvfat.c index f9bf840..e76b42d 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2993,11 +2993,35 @@ DLOG(checkpoint()); vvfat_close_current_file(s); + if (sector_num == s->offset_to_bootsector && nb_sectors == 1) { + /* + * Write on bootsector. Allow only changing the reserved1 field, + * used to mark volume dirtiness + */ + unsigned char *bootsector = s->first_sectors + + s->offset_to_bootsector * 0x200; + /* + * LATER TODO: if FAT32, this is wrong (see init_directories(), + * which always creates a FAT16 bootsector) + */ + const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1); + + for (i = 0; i < 0x200; i++) { + if (i != reserved1_offset && bootsector[i] != buf[i]) { + fprintf(stderr, "Tried to write to protected bootsector\n"); + return -1; + } + } + + /* Update bootsector with the only updatable byte, and return success */ + bootsector[reserved1_offset] = buf[reserved1_offset]; + return 0; + } + /* * Some sanity checks: * - do not allow writing to the boot sector */ - if (sector_num < s->offset_to_fat) return -1; |