summaryrefslogtreecommitdiffstats
path: root/block/vvfat.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/vvfat.c')
-rw-r--r--block/vvfat.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/block/vvfat.c b/block/vvfat.c
index d6dd919683..c5b1442145 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -499,7 +499,7 @@ static bool valid_filename(const unsigned char *name)
(c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
c > 127 ||
- strchr("$%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
+ strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
{
return false;
}
@@ -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;
@@ -3146,10 +3170,9 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
array_init(&(s->commits), sizeof(commit_t));
- s->qcow_filename = g_malloc(PATH_MAX);
- ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "can't create temporary file");
+ s->qcow_filename = create_tmp_file(errp);
+ if (!s->qcow_filename) {
+ ret = -ENOENT;
goto err;
}