vpc-img: implemented check_format() for image autodetection
This commit is contained in:
parent
be1642e02e
commit
d6bdc0c18f
@ -234,7 +234,7 @@ int hdimage_detect_image_mode(const char *pathname)
|
|||||||
result = BX_HDIMAGE_MODE_VMWARE4;
|
result = BX_HDIMAGE_MODE_VMWARE4;
|
||||||
} else if (growing_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) {
|
} else if (growing_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) {
|
||||||
result = BX_HDIMAGE_MODE_GROWING;
|
result = BX_HDIMAGE_MODE_GROWING;
|
||||||
} else if (vpc_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) {
|
} else if (vpc_image_t::check_format(fd, image_size) >= HDIMAGE_FORMAT_OK) {
|
||||||
result = BX_HDIMAGE_MODE_VPC;
|
result = BX_HDIMAGE_MODE_VPC;
|
||||||
} else if (default_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) {
|
} else if (default_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) {
|
||||||
result = BX_HDIMAGE_MODE_FLAT;
|
result = BX_HDIMAGE_MODE_FLAT;
|
||||||
|
@ -52,44 +52,31 @@
|
|||||||
#define cpu_to_be32(val) (val)
|
#define cpu_to_be32(val) (val)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int vpc_image_t::vpc_check_header(const char* _pathname, int* disk_type)
|
int vpc_image_t::check_format(int fd, Bit64u imgsize)
|
||||||
{
|
{
|
||||||
int filedes, vpc_disk_type;
|
Bit8u temp_footer_buf[HEADER_SIZE];
|
||||||
Bit64u imgsize;
|
|
||||||
vhd_footer_t *footer;
|
vhd_footer_t *footer;
|
||||||
|
int vpc_disk_type = VHD_DYNAMIC;
|
||||||
|
|
||||||
vpc_disk_type = VHD_DYNAMIC;
|
if (bx_read_image(fd, 0, (char*)temp_footer_buf, HEADER_SIZE) != HEADER_SIZE) {
|
||||||
|
return HDIMAGE_READ_ERROR;
|
||||||
if ((filedes = hdimage_open_file(_pathname, O_RDWR, &imgsize, NULL)) < 0) {
|
|
||||||
BX_ERROR(("VPC: cannot open hdimage file", _pathname));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bx_read_image(filedes, 0, (char*)footer_buf, HEADER_SIZE) != HEADER_SIZE) {
|
footer = (vhd_footer_t*)temp_footer_buf;
|
||||||
BX_ERROR(("VPC: cannot read image file header", _pathname));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer = (vhd_footer_t*)footer_buf;
|
|
||||||
if (strncmp((char*)footer->creator, "conectix", 8)) {
|
if (strncmp((char*)footer->creator, "conectix", 8)) {
|
||||||
if (imgsize < HEADER_SIZE) {
|
if (imgsize < HEADER_SIZE) {
|
||||||
BX_ERROR(("VPC: signature missed", _pathname));
|
return HDIMAGE_NO_SIGNATURE;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
// If a fixed disk, the footer is found only at the end of the file
|
// If a fixed disk, the footer is found only at the end of the file
|
||||||
if (bx_read_image(filedes, imgsize-HEADER_SIZE, (char*)footer_buf, HEADER_SIZE) != HEADER_SIZE) {
|
if (bx_read_image(fd, imgsize-HEADER_SIZE, (char*)temp_footer_buf, HEADER_SIZE) != HEADER_SIZE) {
|
||||||
return -1;
|
return HDIMAGE_READ_ERROR;
|
||||||
}
|
}
|
||||||
if (strncmp((char*)footer->creator, "conectix", 8)) {
|
if (strncmp((char*)footer->creator, "conectix", 8)) {
|
||||||
BX_ERROR(("VPC: signature missed", _pathname));
|
return HDIMAGE_NO_SIGNATURE;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
vpc_disk_type = VHD_FIXED;
|
vpc_disk_type = VHD_FIXED;
|
||||||
}
|
}
|
||||||
if (disk_type != NULL) {
|
return vpc_disk_type;
|
||||||
*disk_type = vpc_disk_type;
|
|
||||||
}
|
|
||||||
return filedes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vpc_image_t::open(const char* _pathname)
|
int vpc_image_t::open(const char* _pathname)
|
||||||
@ -99,11 +86,27 @@ int vpc_image_t::open(const char* _pathname)
|
|||||||
vhd_dyndisk_header_t *dyndisk_header;
|
vhd_dyndisk_header_t *dyndisk_header;
|
||||||
Bit8u buf[HEADER_SIZE];
|
Bit8u buf[HEADER_SIZE];
|
||||||
Bit32u checksum;
|
Bit32u checksum;
|
||||||
|
Bit64u imgsize = 0;
|
||||||
int disk_type;
|
int disk_type;
|
||||||
|
|
||||||
pathname = _pathname;
|
pathname = _pathname;
|
||||||
if ((fd = vpc_check_header(pathname, &disk_type)) < 0) {
|
if ((fd = hdimage_open_file(pathname, O_RDWR, &imgsize, NULL)) < 0) {
|
||||||
::close(fd);
|
BX_ERROR(("VPC: cannot open hdimage file '%s'", pathname));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_type = check_format(fd, imgsize);
|
||||||
|
if (disk_type < 0) {
|
||||||
|
switch (disk_type) {
|
||||||
|
case HDIMAGE_READ_ERROR:
|
||||||
|
BX_ERROR(("VPC: cannot read image file header of '%s'", _pathname));
|
||||||
|
return -1;
|
||||||
|
case HDIMAGE_NO_SIGNATURE:
|
||||||
|
BX_ERROR(("VPC: signature missed in file '%s'", _pathname));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bx_read_image(fd, 0, (char*)footer_buf, HEADER_SIZE) != HEADER_SIZE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
footer = (vhd_footer_t*)footer_buf;
|
footer = (vhd_footer_t*)footer_buf;
|
||||||
@ -288,12 +291,19 @@ bx_bool vpc_image_t::save_state(const char *backup_fname)
|
|||||||
void vpc_image_t::restore_state(const char *backup_fname)
|
void vpc_image_t::restore_state(const char *backup_fname)
|
||||||
{
|
{
|
||||||
int temp_fd;
|
int temp_fd;
|
||||||
|
Bit64u imgsize;
|
||||||
|
|
||||||
if ((temp_fd = vpc_check_header(backup_fname, NULL)) < 0) {
|
if ((temp_fd = hdimage_open_file(backup_fname, O_RDWR, &imgsize, NULL)) < 0) {
|
||||||
|
BX_PANIC(("cannot open vpc image backup '%s'", backup_fname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_format(temp_fd, imgsize) < HDIMAGE_FORMAT_OK) {
|
||||||
::close(temp_fd);
|
::close(temp_fd);
|
||||||
BX_PANIC(("Could not detect vpc image header"));
|
BX_PANIC(("Could not detect vpc image header"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
::close(temp_fd);
|
||||||
close();
|
close();
|
||||||
if (!hdimage_copy_file(backup_fname, pathname)) {
|
if (!hdimage_copy_file(backup_fname, pathname)) {
|
||||||
BX_PANIC(("Failed to restore vpc image '%s'", pathname));
|
BX_PANIC(("Failed to restore vpc image '%s'", pathname));
|
||||||
|
@ -143,12 +143,14 @@ class vpc_image_t : public device_image_t
|
|||||||
Bit64s lseek(Bit64s offset, int whence);
|
Bit64s lseek(Bit64s offset, int whence);
|
||||||
ssize_t read(void* buf, size_t count);
|
ssize_t read(void* buf, size_t count);
|
||||||
ssize_t write(const void* buf, size_t count);
|
ssize_t write(const void* buf, size_t count);
|
||||||
|
|
||||||
Bit32u get_capabilities();
|
Bit32u get_capabilities();
|
||||||
|
static int check_format(int fd, Bit64u imgsize);
|
||||||
|
|
||||||
bx_bool save_state(const char *backup_fname);
|
bx_bool save_state(const char *backup_fname);
|
||||||
void restore_state(const char *backup_fname);
|
void restore_state(const char *backup_fname);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int vpc_check_header(const char* pathname, int *disk_type);
|
|
||||||
Bit32u vpc_checksum(Bit8u *buf, size_t size);
|
Bit32u vpc_checksum(Bit8u *buf, size_t size);
|
||||||
Bit64s get_sector_offset(Bit64s sector_num, int write);
|
Bit64s get_sector_offset(Bit64s sector_num, int write);
|
||||||
int rewrite_footer(void);
|
int rewrite_footer(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user