MiniVHD: Report read/write errors
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user