MiniVHD: Report read/write errors

This commit is contained in:
RichardG867
2024-10-29 15:14:27 -03:00
parent cc9c48711a
commit 2184a982f8
3 changed files with 69 additions and 31 deletions

View File

@@ -529,8 +529,11 @@ hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
size_t num_read;
if (hdd_images[id].type == HDD_IMAGE_VHD) {
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
hdd_images[id].vhd->error = 0;
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
if (hdd_images[id].vhd->error)
return -1;
} else {
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) {
hdd_image_log("Hard disk image %i: Read error during seek\n", id);
@@ -582,8 +585,11 @@ hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
size_t num_write;
if (hdd_images[id].type == HDD_IMAGE_VHD) {
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
hdd_images[id].vhd->error = 0;
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
if (hdd_images[id].vhd->error)
return -1;
} else {
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) {
hdd_image_log("Hard disk image %i: Write error during seek\n", id);
@@ -621,8 +627,11 @@ int
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
{
if (hdd_images[id].type == HDD_IMAGE_VHD) {
hdd_images[id].vhd->error = 0;
int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count);
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
if (hdd_images[id].vhd->error)
return -1;
} else {
memset(empty_sector, 0, 512);

View File

@@ -115,6 +115,7 @@ typedef struct MVHDSparseHeader {
struct MVHDMeta {
FILE* f;
bool readonly;
bool error;
char filename[MVHD_MAX_PATH_BYTES];
struct MVHDMeta* parent;
MVHDFooter footer;
@@ -271,7 +272,7 @@ struct MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t
* \param [in] f File to write sectors to
* \param [in] sector_count The number of sectors to write
*/
void mvhd_write_empty_sectors(FILE* f, int sector_count);
bool mvhd_write_empty_sectors(FILE* f, int sector_count);
/**
* \brief Read a fixed VHD image

View File

@@ -82,15 +82,18 @@ check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *tra
}
}
void
bool
mvhd_write_empty_sectors(FILE *f, int sector_count)
{
uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0};
for (int i = 0; i < sector_count; i++)
fwrite(zero_bytes, sizeof zero_bytes, 1, f);
for (int i = 0; i < sector_count; i++) {
if (!fwrite(zero_bytes, sizeof zero_bytes, 1, f))
return 0;
}
fflush(f);
return 1;
}
/**
@@ -107,7 +110,8 @@ read_sect_bitmap(MVHDMeta *vhdm, int blk)
{
if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) {
mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET);
(void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f);
if (!fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f))
vhdm->error = 1;
} else
memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE);
@@ -124,8 +128,10 @@ write_curr_sect_bitmap(MVHDMeta* vhdm)
{
if (vhdm->bitmap.curr_block >= 0) {
int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE;
mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET);
fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f);
if (mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET) == -1)
vhdm->error = 1;
if (!fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f))
vhdm->error = 1;
}
}
@@ -141,8 +147,10 @@ write_bat_entry(MVHDMeta *vhdm, int blk)
uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset);
uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]);
mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET);
fwrite(&offset, sizeof offset, 1, vhdm->f);
if (mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET) == -1)
vhdm->error = 1;
if (!fwrite(&offset, sizeof offset, 1, vhdm->f))
vhdm->error = 1;
fflush(vhdm->f);
}
@@ -173,7 +181,8 @@ create_block(MVHDMeta *vhdm, int blk)
if (!mvhd_is_conectix_str(footer)) {
/* Oh dear. We use the header instead, since something has gone wrong at the footer */
mvhd_fseeko64(vhdm->f, 0, SEEK_SET);
(void) !fread(footer, sizeof footer, 1, vhdm->f);
if (!fread(footer, sizeof footer, 1, vhdm->f))
vhdm->error = 1;
mvhd_fseeko64(vhdm->f, 0, SEEK_END);
}
@@ -182,20 +191,25 @@ create_block(MVHDMeta *vhdm, int blk)
/* Yikes! We're supposed to be on a sector boundary. Add some padding */
int64_t padding_amount = ((int64_t) MVHD_SECTOR_SIZE) - (abs_offset % MVHD_SECTOR_SIZE);
uint8_t zero_byte = 0;
for (int i = 0; i < padding_amount; i++)
fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f);
for (int i = 0; i < padding_amount; i++) {
if (!fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f))
vhdm->error = 1;
}
abs_offset += padding_amount;
}
uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE);
int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE;
mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors);
if (!mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors))
vhdm->error = 1;
/* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */
mvhd_write_empty_sectors(vhdm->f, 5);
if (!mvhd_write_empty_sectors(vhdm->f, 5))
vhdm->error = 1;
/* And we finish with the footer */
fwrite(footer, sizeof footer, 1, vhdm->f);
if (!fwrite(footer, sizeof footer, 1, vhdm->f))
vhdm->error = 1;
/* We no longer have a sparse block. Update that BAT! */
vhdm->block_offset[blk] = sect_offset;
@@ -214,8 +228,10 @@ mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff
check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors);
addr = ((int64_t) offset) * MVHD_SECTOR_SIZE;
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
(void) !fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f);
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
vhdm->error = 1;
if (!fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f))
vhdm->error = 1;
return truncated_sectors;
}
@@ -245,17 +261,20 @@ mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buf
prev_blk = blk;
if (vhdm->bitmap.curr_block != blk) {
read_sect_bitmap(vhdm, blk);
mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR);
if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1)
vhdm->error = 1;
} else {
addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) *
MVHD_SECTOR_SIZE;
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
vhdm->error = 1;
}
}
if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib))
(void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
else {
if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) {
if (!fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f))
vhdm->error = 1;
} else {
memset(buff, 0, MVHD_SECTOR_SIZE);
mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR);
}
@@ -301,6 +320,10 @@ mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff)
mvhd_sparse_read(curr_vhdm, s, 1, buff);
else
mvhd_fixed_read(curr_vhdm, s, 1, buff);
if (curr_vhdm->error) {
curr_vhdm->error = 0;
vhdm->error = 1;
}
curr_vhdm = vhdm;
buff += MVHD_SECTOR_SIZE;
@@ -320,8 +343,10 @@ mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff
check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors);
addr = (int64_t)offset * MVHD_SECTOR_SIZE;
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f);
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
vhdm->error = 1;
if (!fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f))
vhdm->error = 1;
fflush(vhdm->f);
return truncated_sectors;
@@ -364,16 +389,19 @@ mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *i
if (blk != prev_blk) {
if (vhdm->bitmap.curr_block != blk) {
read_sect_bitmap(vhdm, blk);
mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR);
if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1)
vhdm->error = 1;
} else {
addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) *
MVHD_SECTOR_SIZE;
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
vhdm->error = 1;
}
prev_blk = blk;
}
fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
if (!fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f))
vhdm->error = 1;
VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib);
buff += MVHD_SECTOR_SIZE;
}