Add VHD support.
This commit is contained in:
@@ -981,6 +981,11 @@ load_hard_disks(void)
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
/*
|
||||
* ANOTHER NOTE:
|
||||
* When loading differencing VHDs, the absolute path is required.
|
||||
* So we should not convert absolute paths to relative. -sards
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
|
@@ -32,14 +32,21 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/random.h>
|
||||
#include <86box/hdd.h>
|
||||
#include "minivhd/minivhd.h"
|
||||
#include "minivhd/minivhd_internal.h"
|
||||
|
||||
#define HDD_IMAGE_RAW 0
|
||||
#define HDD_IMAGE_HDI 1
|
||||
#define HDD_IMAGE_HDX 2
|
||||
#define HDD_IMAGE_VHD 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE *file;
|
||||
FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */
|
||||
MVHDMeta* vhd; /* Used for HDD_IMAGE_VHD. */
|
||||
uint32_t base;
|
||||
uint32_t pos, last_sector;
|
||||
uint8_t type;
|
||||
uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */
|
||||
uint8_t loaded;
|
||||
} hdd_image_t;
|
||||
|
||||
@@ -59,16 +66,15 @@ hdd_image_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (hdd_image_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define hdd_image_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
image_is_hdi(const wchar_t *s)
|
||||
{
|
||||
@@ -77,12 +83,12 @@ image_is_hdi(const wchar_t *s)
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (! wcscasecmp(ext, L".HDI"))
|
||||
return 1;
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,34 +103,34 @@ image_is_hdx(const wchar_t *s, int check_signature)
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcscasecmp(ext, L".HDX") == 0) {
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t *)s, L"rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
if (fseeko64(f, 0, SEEK_END))
|
||||
fatal("image_is_hdx(): Error while seeking");
|
||||
filelen = ftello64(f);
|
||||
if (fseeko64(f, 0, SEEK_SET))
|
||||
fatal("image_is_hdx(): Error while seeking");
|
||||
if (filelen < 44) {
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (fread(&signature, 1, 8, f) != 8)
|
||||
fatal("image_is_hdx(): Error reading signature\n");
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t *)s, L"rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
if (fseeko64(f, 0, SEEK_END))
|
||||
fatal("image_is_hdx(): Error while seeking");
|
||||
filelen = ftello64(f);
|
||||
if (fseeko64(f, 0, SEEK_SET))
|
||||
fatal("image_is_hdx(): Error while seeking");
|
||||
if (filelen < 44) {
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (fread(&signature, 1, 8, f) != 8)
|
||||
fatal("image_is_hdx(): Error reading signature\n");
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,22 +138,26 @@ int
|
||||
image_is_vhd(const wchar_t *s, int check_signature)
|
||||
{
|
||||
int len;
|
||||
FILE* f;
|
||||
char *ws = (char *) s;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcscasecmp(ext, L".VHD") == 0) {
|
||||
if (check_signature) {
|
||||
// if is VHD
|
||||
return 1;
|
||||
// else
|
||||
// return 0;
|
||||
} else
|
||||
return 1;
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t*)s, L"rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
bool is_vhd = mvhd_file_is_vhd(f);
|
||||
fclose(f);
|
||||
return is_vhd ? 1 : 0;
|
||||
} else
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -158,28 +168,28 @@ hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size)
|
||||
uint64_t ts = ((uint64_t) size) << 11LL;
|
||||
uint32_t spt, heads, cyl, cth;
|
||||
if (ts > 65535 * 16 * 255)
|
||||
ts = 65535 * 16 * 255;
|
||||
ts = 65535 * 16 * 255;
|
||||
|
||||
if (ts >= 65535 * 16 * 63) {
|
||||
spt = 255;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
spt = 255;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
} else {
|
||||
spt = 17;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
heads = (cth +1023) / 1024;
|
||||
if (heads < 4)
|
||||
heads = 4;
|
||||
if ((cth >= (heads * 1024)) || (heads > 16)) {
|
||||
spt = 31;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
}
|
||||
if (cth >= (heads * 1024)) {
|
||||
spt = 63;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
}
|
||||
spt = 17;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
heads = (cth +1023) / 1024;
|
||||
if (heads < 4)
|
||||
heads = 4;
|
||||
if ((cth >= (heads * 1024)) || (heads > 16)) {
|
||||
spt = 31;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
}
|
||||
if (cth >= (heads * 1024)) {
|
||||
spt = 63;
|
||||
heads = 16;
|
||||
cth = (uint32_t) (ts / spt);
|
||||
}
|
||||
}
|
||||
cyl = cth / heads;
|
||||
*c = cyl;
|
||||
@@ -209,18 +219,18 @@ prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
||||
|
||||
/* First, write all the 1 MB blocks. */
|
||||
if (t > 0) {
|
||||
for (i = 0; i < t; i++) {
|
||||
fseek(hdd_images[id].file, 0, SEEK_END);
|
||||
fwrite(empty_sector_1mb, 1, 1048576, hdd_images[id].file);
|
||||
pclog("#");
|
||||
}
|
||||
for (i = 0; i < t; i++) {
|
||||
fseek(hdd_images[id].file, 0, SEEK_END);
|
||||
fwrite(empty_sector_1mb, 1, 1048576, hdd_images[id].file);
|
||||
pclog("#");
|
||||
}
|
||||
}
|
||||
|
||||
/* Then, write the remainder. */
|
||||
if (size > 0) {
|
||||
fseek(hdd_images[id].file, 0, SEEK_END);
|
||||
fwrite(empty_sector_1mb, 1, size, hdd_images[id].file);
|
||||
pclog("#");
|
||||
fseek(hdd_images[id].file, 0, SEEK_END);
|
||||
fwrite(empty_sector_1mb, 1, size, hdd_images[id].file);
|
||||
pclog("#");
|
||||
}
|
||||
pclog("]\n");
|
||||
/* Switch the suppression of seen messages back on. */
|
||||
@@ -242,7 +252,7 @@ hdd_image_init(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HDD_NUM; i++)
|
||||
memset(&hdd_images[i], 0, sizeof(hdd_image_t));
|
||||
memset(&hdd_images[i], 0, sizeof(hdd_image_t));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -256,19 +266,25 @@ hdd_image_load(int id)
|
||||
int c, ret;
|
||||
uint64_t s = 0;
|
||||
wchar_t *fn = hdd[id].fn;
|
||||
char fn_multibyte_buf[1200];
|
||||
int is_hdx[2] = { 0, 0 };
|
||||
int is_vhd[2] = { 0, 0 };
|
||||
int is_vhd[2] = { 0, 0 };
|
||||
int vhd_error = 0;
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
|
||||
hdd_images[id].base = 0;
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
if (hdd_images[id].file) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
else if (hdd_images[id].vhd) {
|
||||
mvhd_close(hdd_images[id].vhd);
|
||||
hdd_images[id].vhd = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
||||
is_hdx[0] = image_is_hdx(fn, 0);
|
||||
@@ -281,172 +297,199 @@ hdd_image_load(int id)
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.') {
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].file = plat_fopen(fn, L"rb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT) {
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdd[id].wp) {
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT) {
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdd[id].wp) {
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdd_images[id].file = plat_fopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 1;
|
||||
} else if (is_hdx[0]) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
hdd_images[id].type = 0;
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
hdd_images[id].file = plat_fopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = HDD_IMAGE_HDI;
|
||||
} else if (is_hdx[0]) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = HDD_IMAGE_HDX;
|
||||
} else if (is_vhd[0]) {
|
||||
fclose(hdd_images[id].file);
|
||||
MVHDGeom geometry;
|
||||
geometry.cyl = hdd[id].tracks;
|
||||
geometry.heads = hdd[id].hpc;
|
||||
geometry.spt = hdd[id].spt;
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
|
||||
s = full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
wcstombs(fn_multibyte_buf, fn, sizeof fn_multibyte_buf);
|
||||
hdd_images[id].vhd = mvhd_create_fixed(fn_multibyte_buf, geometry, &vhd_error, NULL);
|
||||
if (hdd_images[id].vhd == NULL)
|
||||
fatal("hdd_image_load(): VHD: Could not create VHD : %s\n", mvhd_strerr(vhd_error));
|
||||
|
||||
ret = prepare_new_hard_disk(id, full_size);
|
||||
hdd_images[id].type = HDD_IMAGE_VHD;
|
||||
return 1;
|
||||
} else {
|
||||
hdd_images[id].type = HDD_IMAGE_RAW;
|
||||
}
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
|
||||
if (is_vhd[0]) {
|
||||
/* VHD image. */
|
||||
hdd_images[id].type = 3;
|
||||
}
|
||||
s = full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
ret = prepare_new_hard_disk(id, full_size);
|
||||
return ret;
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
if (fseeko64(hdd_images[id].file, 0x8, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offset 0x8\n");
|
||||
if (fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading base offset\n");
|
||||
if (fseeko64(hdd_images[id].file, 0xC, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offest 0xC\n");
|
||||
full_size = 0LL;
|
||||
if (fread(&full_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading full size\n");
|
||||
if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offset 0x10\n");
|
||||
if (fread(§or_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sector size\n");
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
if (fread(&spt, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sectors per track\n");
|
||||
if (fread(&hpc, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n");
|
||||
if (fread(&tracks, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading number of tracks\n");
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = 1;
|
||||
} else if (is_hdx[1]) {
|
||||
hdd_images[id].base = 0x28;
|
||||
if (fseeko64(hdd_images[id].file, 8, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDX: Error seeking to offset 0x8\n");
|
||||
if (fread(&full_size, 1, 8, hdd_images[id].file) != 8)
|
||||
fatal("hdd_image_load(): HDX: Error reading full size\n");
|
||||
if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDX: Error seeking to offset 0x10\n");
|
||||
if (fread(§or_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDX: Error reading sector size\n");
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
if (fread(&spt, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sectors per track\n");
|
||||
if (fread(&hpc, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n");
|
||||
if (fread(&tracks, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDX: Error reading number of tracks\n");
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = 2;
|
||||
} else if (is_vhd[1]) {
|
||||
// full_size = VHD size in bytes
|
||||
// hdd[id].tracks = VHD cylinders
|
||||
// hdd[id].hpc = VHD heads
|
||||
// hdd[id].spt = VHD spt
|
||||
hdd_images[id].type = 3;
|
||||
/* If we're here, this means there is a valid VHD footer in the
|
||||
image, which means that by definition, all valid sectors
|
||||
are there. */
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
return 1;
|
||||
} else {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
if (image_is_hdi(fn)) {
|
||||
if (fseeko64(hdd_images[id].file, 0x8, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offset 0x8\n");
|
||||
if (fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading base offset\n");
|
||||
if (fseeko64(hdd_images[id].file, 0xC, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offest 0xC\n");
|
||||
full_size = 0LL;
|
||||
if (fread(&full_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading full size\n");
|
||||
if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDI: Error seeking to offset 0x10\n");
|
||||
if (fread(§or_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sector size\n");
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
if (fread(&spt, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sectors per track\n");
|
||||
if (fread(&hpc, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n");
|
||||
if (fread(&tracks, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading number of tracks\n");
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = HDD_IMAGE_HDI;
|
||||
} else if (is_hdx[1]) {
|
||||
hdd_images[id].base = 0x28;
|
||||
if (fseeko64(hdd_images[id].file, 8, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDX: Error seeking to offset 0x8\n");
|
||||
if (fread(&full_size, 1, 8, hdd_images[id].file) != 8)
|
||||
fatal("hdd_image_load(): HDX: Error reading full size\n");
|
||||
if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1)
|
||||
fatal("hdd_image_load(): HDX: Error seeking to offset 0x10\n");
|
||||
if (fread(§or_size, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDX: Error reading sector size\n");
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
if (fread(&spt, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading sectors per track\n");
|
||||
if (fread(&hpc, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n");
|
||||
if (fread(&tracks, 1, 4, hdd_images[id].file) != 4)
|
||||
fatal("hdd_image_load(): HDX: Error reading number of tracks\n");
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = HDD_IMAGE_HDX;
|
||||
} else if (is_vhd[1]) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
wcstombs(fn_multibyte_buf, fn, sizeof fn_multibyte_buf);
|
||||
hdd_images[id].vhd = mvhd_open(fn_multibyte_buf, (bool)0, &vhd_error);
|
||||
if (hdd_images[id].vhd == NULL)
|
||||
{
|
||||
if (vhd_error == MVHD_ERR_FILE)
|
||||
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn_multibyte_buf, strerror(mvhd_errno));
|
||||
else
|
||||
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn_multibyte_buf, mvhd_strerr(vhd_error));
|
||||
}
|
||||
else if (vhd_error == MVHD_ERR_TIMESTAMP)
|
||||
{
|
||||
fatal("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn_multibyte_buf);
|
||||
}
|
||||
|
||||
full_size = hdd_images[id].vhd->footer.curr_sz;
|
||||
hdd[id].tracks = hdd_images[id].vhd->footer.geom.cyl;
|
||||
hdd[id].hpc = hdd_images[id].vhd->footer.geom.heads;
|
||||
hdd[id].spt = hdd_images[id].vhd->footer.geom.spt;
|
||||
hdd_images[id].type = HDD_IMAGE_VHD;
|
||||
/* If we're here, this means there is a valid VHD footer in the
|
||||
image, which means that by definition, all valid sectors
|
||||
are there. */
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
return 1;
|
||||
} else {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].type = HDD_IMAGE_RAW;
|
||||
}
|
||||
}
|
||||
|
||||
if (fseeko64(hdd_images[id].file, 0, SEEK_END) == -1)
|
||||
fatal("hdd_image_load(): Error seeking to the end of file\n");
|
||||
fatal("hdd_image_load(): Error seeking to the end of file\n");
|
||||
s = ftello64(hdd_images[id].file);
|
||||
if (s < (full_size + hdd_images[id].base))
|
||||
ret = prepare_new_hard_disk(id, full_size);
|
||||
ret = prepare_new_hard_disk(id, full_size);
|
||||
else {
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
ret = 1;
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -460,36 +503,47 @@ hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
addr = (uint64_t)sector << 9LL;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1)
|
||||
fatal("hdd_image_seek(): Error seeking\n");
|
||||
if (hdd_images[id].type != HDD_IMAGE_VHD) {
|
||||
if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1)
|
||||
fatal("hdd_image_seek(): Error seeking\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
int i;
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
int non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Read error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Read error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
|
||||
hdd_images[id].pos = sector + i;
|
||||
fread(buffer + (i << 9), 1, 512, hdd_images[id].file);
|
||||
}
|
||||
hdd_images[id].pos = sector + i;
|
||||
fread(buffer + (i << 9), 1, 512, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
hdd_sectors(uint8_t id)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
return (uint32_t) ((ftello64(hdd_images[id].file) - hdd_images[id].base) >> 9);
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
return (uint32_t) (hdd_images[id].vhd->footer.curr_sz >> 9);
|
||||
} else {
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
return (uint32_t)((ftello64(hdd_images[id].file) - hdd_images[id].base) >> 9);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -500,12 +554,12 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_image_read(id, sector, transfer_sectors, buffer);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -513,20 +567,25 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
void
|
||||
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
int i;
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
int non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Write error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Write error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
|
||||
hdd_images[id].pos = sector + i;
|
||||
fwrite(buffer + (i << 9), 512, 1, hdd_images[id].file);
|
||||
}
|
||||
hdd_images[id].pos = sector + i;
|
||||
fwrite(buffer + (i << 9), 512, 1, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -537,12 +596,12 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_image_write(id, sector, transfer_sectors, buffer);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -550,22 +609,27 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
void
|
||||
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
} else {
|
||||
uint32_t i = 0;
|
||||
|
||||
memset(empty_sector, 0, 512);
|
||||
memset(empty_sector, 0, 512);
|
||||
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Zero error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Zero error during seek\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (feof(hdd_images[id].file))
|
||||
break;
|
||||
|
||||
hdd_images[id].pos = sector + i;
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
}
|
||||
hdd_images[id].pos = sector + i;
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -576,12 +640,12 @@ hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_image_zero(id, sector, transfer_sectors);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -611,21 +675,24 @@ void
|
||||
hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
{
|
||||
if (wcslen(hdd[id].fn) == 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
} else if (hdd_images[id].vhd != NULL) {
|
||||
mvhd_close(hdd_images[id].vhd);
|
||||
hdd_images[id].vhd = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = -1;
|
||||
|
||||
memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn));
|
||||
if (fn_preserve)
|
||||
wcscpy(hdd[id].prev_fn, hdd[id].fn);
|
||||
wcscpy(hdd[id].prev_fn, hdd[id].fn);
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
}
|
||||
|
||||
@@ -636,12 +703,16 @@ hdd_image_close(uint8_t id)
|
||||
hdd_image_log("hdd_image_close(%i)\n", id);
|
||||
|
||||
if (!hdd_images[id].loaded)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
} else if (hdd_images[id].vhd != NULL) {
|
||||
mvhd_close(hdd_images[id].vhd);
|
||||
hdd_images[id].vhd = NULL;
|
||||
}
|
||||
|
||||
memset(&hdd_images[id], 0, sizeof(hdd_image_t));
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
@@ -140,6 +140,12 @@
|
||||
#define IDS_4119 4119 // "Unsupported disk image"
|
||||
#define IDS_4120 4120 // "Overwrite"
|
||||
#define IDS_4121 4121 // "Don't Overwrite"
|
||||
#define IDS_4122 4122 // "Raw image (.img)"
|
||||
#define IDS_4123 4123 // "HDI image (.hdi)"
|
||||
#define IDS_4124 4124 // "HDX image (.hdx)"
|
||||
#define IDS_4125 4125 // "Fixed-size VHD (.vhd)"
|
||||
#define IDS_4126 4126 // "Dynamic-size VHD (.vhd)"
|
||||
#define IDS_4127 4127 // "Differencing VHD (.vhd)"
|
||||
|
||||
#define IDS_4352 4352 // "MFM/RLL"
|
||||
#define IDS_4353 4353 // "XT IDE"
|
||||
@@ -209,7 +215,7 @@
|
||||
|
||||
#define STR_NUM_2048 92
|
||||
#define STR_NUM_3072 11
|
||||
#define STR_NUM_4096 18
|
||||
#define STR_NUM_4096 32
|
||||
#define STR_NUM_4352 6
|
||||
#define STR_NUM_4608 6
|
||||
#define STR_NUM_5120 1
|
||||
|
@@ -105,6 +105,8 @@
|
||||
#define IDT_1771 1771 /* ID: */
|
||||
#define IDT_1772 1772 /* Channel */
|
||||
#define IDT_1773 1773 /* Type: */
|
||||
#define IDT_1774 1774 /* Image Format: */
|
||||
#define IDT_1775 1775 /* Block Size: */
|
||||
|
||||
|
||||
/*
|
||||
@@ -218,6 +220,8 @@
|
||||
#define IDC_EDIT_HD_SIZE 1164
|
||||
#define IDC_COMBO_HD_TYPE 1165
|
||||
#define IDC_PBAR_IMG_CREATE 1166
|
||||
#define IDC_COMBO_HD_IMG_FORMAT 1167
|
||||
#define IDC_COMBO_HD_BLOCK_SIZE 1168
|
||||
|
||||
#define IDC_REMOV_DEVICES 1170 /* floppy and cd-rom drives config */
|
||||
#define IDC_LIST_FLOPPY_DRIVES 1171
|
||||
|
@@ -193,11 +193,12 @@ extern int MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPara
|
||||
|
||||
|
||||
/* Functions in win_dialog.c: */
|
||||
extern int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save);
|
||||
extern int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save);
|
||||
extern int file_dlg_mb(HWND hwnd, char *f, char *fn, int save);
|
||||
extern int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save);
|
||||
extern int file_dlg_st(HWND hwnd, int i, char *fn, int save);
|
||||
/* Pass NULL in the title param to use the default title. */
|
||||
extern int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save);
|
||||
extern int file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save);
|
||||
extern int file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save);
|
||||
extern int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, char *title, int save);
|
||||
extern int file_dlg_st(HWND hwnd, int i, char *fn, char *title, int save);
|
||||
|
||||
extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title);
|
||||
|
||||
|
@@ -575,13 +575,13 @@ BEGIN
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111
|
||||
DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 149
|
||||
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Add Hard Disk"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,55,89,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,55,127,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,112,127,50,14
|
||||
EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12
|
||||
PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12
|
||||
EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12
|
||||
@@ -607,6 +607,12 @@ BEGIN
|
||||
LTEXT "ID:",IDT_1723,99,73,34,8
|
||||
COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Image Format:",IDT_1774,7,92,50,12
|
||||
COMBOBOX IDC_COMBO_HD_IMG_FORMAT,58,90,153,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Block Size:",IDT_1775,7,111,50,12
|
||||
COMBOBOX IDC_COMBO_HD_BLOCK_SIZE,58,109,153,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Progress:",IDT_1752,7,7,204,9
|
||||
CONTROL "IMGCreateProgress",IDC_PBAR_IMG_CREATE,"msctls_progress32",PBS_SMOOTH |
|
||||
WS_BORDER,7,16,204,12
|
||||
@@ -1055,6 +1061,12 @@ BEGIN
|
||||
IDS_4119 "Unsupported disk image"
|
||||
IDS_4120 "Overwrite"
|
||||
IDS_4121 "Don't Overwrite"
|
||||
IDS_4122 "Raw image (.img)"
|
||||
IDS_4123 "HDI image (.hdi)"
|
||||
IDS_4124 "HDX image (.hdx)"
|
||||
IDS_4125 "Fixed-size VHD (.vhd)"
|
||||
IDS_4126 "Dynamic-size VHD (.vhd)"
|
||||
IDS_4127 "Differencing VHD (.vhd)"
|
||||
|
||||
IDS_4352 "MFM/RLL"
|
||||
IDS_4353 "XTA"
|
||||
|
@@ -412,7 +412,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
ws[c] = 0;
|
||||
}
|
||||
|
||||
if (!file_dlg(hdlg, ws, s, 0))
|
||||
if (!file_dlg(hdlg, ws, s, NULL, 0))
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)wopenfilestring);
|
||||
}
|
||||
break;
|
||||
|
@@ -152,7 +152,7 @@ ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, voi
|
||||
|
||||
|
||||
int
|
||||
file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save)
|
||||
file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save)
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
BOOL r;
|
||||
@@ -177,7 +177,9 @@ file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save)
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
if (! save)
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
if (title)
|
||||
ofn.lpstrTitle = title;
|
||||
|
||||
/* Display the Open dialog box. */
|
||||
if (save)
|
||||
@@ -199,37 +201,44 @@ file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save)
|
||||
|
||||
|
||||
int
|
||||
file_dlg(HWND hwnd, WCHAR *f, char *fn, int save)
|
||||
file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save)
|
||||
{
|
||||
WCHAR ufn[512];
|
||||
WCHAR ufn[512], title_buf[512];
|
||||
|
||||
mbstowcs(ufn, fn, strlen(fn) + 1);
|
||||
if (title)
|
||||
mbstowcs(title_buf, title, sizeof title_buf);
|
||||
|
||||
return(file_dlg_w(hwnd, f, ufn, save));
|
||||
return(file_dlg_w(hwnd, f, ufn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_mb(HWND hwnd, char *f, char *fn, int save)
|
||||
file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save)
|
||||
{
|
||||
WCHAR uf[512], ufn[512];
|
||||
WCHAR uf[512], ufn[512], title_buf[512];
|
||||
|
||||
mbstowcs(uf, f, strlen(fn) + 1);
|
||||
mbstowcs(ufn, fn, strlen(fn) + 1);
|
||||
if (title)
|
||||
mbstowcs(title_buf, title, sizeof title_buf);
|
||||
|
||||
return(file_dlg_w(hwnd, uf, ufn, save));
|
||||
return(file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, int save)
|
||||
file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, char *title, int save)
|
||||
{
|
||||
return(file_dlg_w(hwnd, plat_get_string(id), fn, save));
|
||||
WCHAR title_buf[512];
|
||||
if (title)
|
||||
mbstowcs(title_buf, title, sizeof title_buf);
|
||||
return(file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_st(HWND hwnd, int id, char *fn, int save)
|
||||
{
|
||||
return(file_dlg(hwnd, plat_get_string(id), fn, save));
|
||||
file_dlg_st(HWND hwnd, int id, char *fn, char *title, int save)
|
||||
{
|
||||
return(file_dlg(hwnd, plat_get_string(id), fn, title, save));
|
||||
}
|
||||
|
@@ -413,7 +413,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
wp = 1;
|
||||
/* FALLTHROUGH */
|
||||
case IDM_FLOPPY_IMAGE_EXISTING:
|
||||
ret = file_dlg_w_st(hwnd, IDS_2109, floppyfns[id], 0);
|
||||
ret = file_dlg_w_st(hwnd, IDS_2109, floppyfns[id], NULL, 0);
|
||||
if (! ret) {
|
||||
floppy_mount(id, wopenfilestring, wp);
|
||||
}
|
||||
@@ -424,7 +424,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
break;
|
||||
|
||||
case IDM_FLOPPY_EXPORT_TO_86F:
|
||||
ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], 1);
|
||||
ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], NULL, 1);
|
||||
if (! ret) {
|
||||
plat_pause(1);
|
||||
ret = d86f_export(id, wopenfilestring);
|
||||
@@ -450,7 +450,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
break;
|
||||
|
||||
case IDM_CDROM_IMAGE:
|
||||
if (!file_dlg_w_st(hwnd, IDS_2075, cdrom[id].image_path, 0)) {
|
||||
if (!file_dlg_w_st(hwnd, IDS_2075, cdrom[id].image_path, NULL, 0)) {
|
||||
cdrom_mount(id, wopenfilestring);
|
||||
}
|
||||
break;
|
||||
@@ -463,7 +463,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
wp = 1;
|
||||
/* FALLTHROUGH */
|
||||
case IDM_ZIP_IMAGE_EXISTING:
|
||||
ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, 0);
|
||||
ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, NULL, 0);
|
||||
if (! ret)
|
||||
zip_mount(id, wopenfilestring, wp);
|
||||
break;
|
||||
@@ -484,7 +484,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
wp = 1;
|
||||
/* FALLTHROUGH */
|
||||
case IDM_MO_IMAGE_EXISTING:
|
||||
ret = file_dlg_w_st(hwnd, IDS_2116, mo_drives[id].image_path, 0);
|
||||
ret = file_dlg_w_st(hwnd, IDS_2116, mo_drives[id].image_path, NULL, 0);
|
||||
if (! ret)
|
||||
mo_mount(id, wopenfilestring, wp);
|
||||
break;
|
||||
|
@@ -777,7 +777,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
return TRUE;
|
||||
|
||||
case IDC_CFILE:
|
||||
if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2139 : (is_zip ? IDS_2055 : IDS_2062)), L"", 1)) {
|
||||
if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2139 : (is_zip ? IDS_2055 : IDS_2062)), L"", NULL, 1)) {
|
||||
if (!wcschr(wopenfilestring, L'.')) {
|
||||
if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) {
|
||||
twcs = &wopenfilestring[wcslen(wopenfilestring)];
|
||||
|
@@ -64,6 +64,8 @@
|
||||
#include <86box/plat_midi.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/win.h>
|
||||
#include "../disk/minivhd/minivhd.h"
|
||||
#include "../disk/minivhd/minivhd_util.h"
|
||||
|
||||
|
||||
/* Icon, Bus, File, C, H, S, Size */
|
||||
@@ -2344,6 +2346,17 @@ set_edit_box_contents(HWND hdlg, int id, uint32_t val)
|
||||
SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText);
|
||||
}
|
||||
|
||||
static void set_edit_box_text_contents(HWND hdlg, int id, WCHAR* text)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(text), (LPARAM) text);
|
||||
}
|
||||
|
||||
static void get_edit_box_text_contents(HWND hdlg, int id, WCHAR* text_buffer, int buffer_size)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, WM_GETTEXT, (WPARAM) buffer_size, (LPARAM) text_buffer);
|
||||
}
|
||||
|
||||
static int hdconf_initialize_hdt_combo(HWND hdlg)
|
||||
{
|
||||
@@ -2387,6 +2400,161 @@ recalc_selection(HWND hdlg)
|
||||
settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection);
|
||||
}
|
||||
|
||||
HWND vhd_progress_hdlg;
|
||||
|
||||
static void vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors)
|
||||
{
|
||||
MSG msg;
|
||||
HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE);
|
||||
SendMessage(h, PBM_SETPOS, (WPARAM) current_sector, (LPARAM) 0);
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry,
|
||||
* we adjust it to the next-largest size that is compatible. On average, this will be a difference
|
||||
* of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more
|
||||
* than a tenth of a percent change in size.
|
||||
*/
|
||||
static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry)
|
||||
{
|
||||
if (_86box_geometry->cyl <= 65535) {
|
||||
vhd_geometry->cyl = _86box_geometry->cyl;
|
||||
vhd_geometry->heads = _86box_geometry->heads;
|
||||
vhd_geometry->spt = _86box_geometry->spt;
|
||||
return;
|
||||
}
|
||||
|
||||
int desired_sectors = _86box_geometry->cyl * _86box_geometry->heads * _86box_geometry->spt;
|
||||
if (desired_sectors > 267321600)
|
||||
desired_sectors = 267321600;
|
||||
|
||||
int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */
|
||||
if (remainder > 0)
|
||||
desired_sectors += (85680 - remainder);
|
||||
|
||||
_86box_geometry->cyl = desired_sectors / (16 * 63);
|
||||
_86box_geometry->heads = 16;
|
||||
_86box_geometry->spt = 63;
|
||||
|
||||
vhd_geometry->cyl = desired_sectors / (16 * 255);
|
||||
vhd_geometry->heads = 16;
|
||||
vhd_geometry->spt = 255;
|
||||
}
|
||||
|
||||
static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry)
|
||||
{
|
||||
if (vhd_geometry->spt <= 63)
|
||||
return;
|
||||
|
||||
int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt;
|
||||
if (desired_sectors > 267321600)
|
||||
desired_sectors = 267321600;
|
||||
|
||||
int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */
|
||||
if (remainder > 0)
|
||||
desired_sectors -= remainder;
|
||||
|
||||
vhd_geometry->cyl = desired_sectors / (16 * 63);
|
||||
vhd_geometry->heads = 16;
|
||||
vhd_geometry->spt = 63;
|
||||
}
|
||||
|
||||
static MVHDGeom create_drive_vhd_fixed(char* filename, int cyl, int heads, int spt)
|
||||
{
|
||||
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
|
||||
MVHDGeom vhd_geometry;
|
||||
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
|
||||
|
||||
HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE);
|
||||
settings_show_window(vhd_progress_hdlg, IDT_1731, FALSE);
|
||||
settings_show_window(vhd_progress_hdlg, IDC_EDIT_HD_FILE_NAME, FALSE);
|
||||
settings_show_window(vhd_progress_hdlg, IDC_CFILE, FALSE);
|
||||
settings_show_window(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE, TRUE);
|
||||
settings_enable_window(vhd_progress_hdlg, IDT_1752, TRUE);
|
||||
SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) vhd_geometry.cyl * vhd_geometry.heads * vhd_geometry.spt);
|
||||
SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
|
||||
|
||||
int vhd_error = 0;
|
||||
MVHDMeta *vhd = mvhd_create_fixed(filename, vhd_geometry, &vhd_error, vhd_progress_callback);
|
||||
if (vhd == NULL)
|
||||
{
|
||||
_86box_geometry.cyl = 0;
|
||||
_86box_geometry.heads = 0;
|
||||
_86box_geometry.spt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mvhd_close(vhd);
|
||||
}
|
||||
|
||||
return _86box_geometry;
|
||||
}
|
||||
|
||||
static MVHDGeom create_drive_vhd_dynamic(char* filename, int cyl, int heads, int spt, int blocksize)
|
||||
{
|
||||
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
|
||||
MVHDGeom vhd_geometry;
|
||||
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
|
||||
int vhd_error = 0;
|
||||
MVHDCreationOptions options;
|
||||
options.block_size_in_sectors = blocksize;
|
||||
options.path = filename;
|
||||
options.size_in_bytes = 0;
|
||||
options.geometry = vhd_geometry;
|
||||
options.type = MVHD_TYPE_DYNAMIC;
|
||||
|
||||
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
|
||||
if (vhd == NULL)
|
||||
{
|
||||
_86box_geometry.cyl = 0;
|
||||
_86box_geometry.heads = 0;
|
||||
_86box_geometry.spt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mvhd_close(vhd);
|
||||
}
|
||||
|
||||
return _86box_geometry;
|
||||
}
|
||||
|
||||
static MVHDGeom create_drive_vhd_diff(char* filename, char* parent_filename, int blocksize)
|
||||
{
|
||||
int vhd_error = 0;
|
||||
MVHDCreationOptions options;
|
||||
options.block_size_in_sectors = blocksize;
|
||||
options.path = filename;
|
||||
options.parent_path = parent_filename;
|
||||
options.type = MVHD_TYPE_DIFF;
|
||||
|
||||
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
|
||||
MVHDGeom vhd_geometry;
|
||||
if (vhd == NULL)
|
||||
{
|
||||
vhd_geometry.cyl = 0;
|
||||
vhd_geometry.heads = 0;
|
||||
vhd_geometry.spt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vhd_geometry = mvhd_get_geometry(vhd);
|
||||
|
||||
if (vhd_geometry.spt > 63)
|
||||
{
|
||||
vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63);
|
||||
vhd_geometry.heads = 16;
|
||||
vhd_geometry.spt = 63;
|
||||
}
|
||||
|
||||
mvhd_close(vhd);
|
||||
}
|
||||
|
||||
return vhd_geometry;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
static LRESULT CALLBACK
|
||||
@@ -2400,19 +2568,26 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
uint32_t temp, i = 0, sector_size = 512;
|
||||
uint32_t zero = 0, base = 0x1000;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t temp_size, r = 0;
|
||||
uint64_t r = 0;
|
||||
char *big_buf;
|
||||
char hd_file_name_multibyte[1200];
|
||||
int b = 0;
|
||||
int vhd_error = 0;
|
||||
uint8_t channel = 0;
|
||||
uint8_t id = 0;
|
||||
wchar_t *twcs;
|
||||
MSG msg;
|
||||
int img_format, block_size;
|
||||
WCHAR text_buf[256];
|
||||
RECT rect;
|
||||
POINT point;
|
||||
int dlg_height_adjust;
|
||||
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
memset(hd_file_name, 0, sizeof(hd_file_name));
|
||||
|
||||
hdd_ptr = &(temp_hdd[next_free_id]);
|
||||
hdd_ptr = &(temp_hdd[next_free_id]);
|
||||
|
||||
SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102));
|
||||
|
||||
@@ -2426,15 +2601,61 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
size = (tracks * hpc * spt) << 9;
|
||||
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL));
|
||||
hdconf_initialize_hdt_combo(hdlg);
|
||||
|
||||
// TODO: Why is it crashing when I try to use string resources here?
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4122));
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4123));
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4124));
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4125));
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4126));
|
||||
// settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4127));
|
||||
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"Raw image (.img)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"HDI image (.hdi)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"HDX image (.hdx)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"Fixed-size VHD (.vhd)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"Dynamic-size VHD (.vhd)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, (LPARAM) L"Differencing VHD (.vhd)");
|
||||
settings_set_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT, 0);
|
||||
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, (LPARAM) L"Large blocks (2 MB)");
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, (LPARAM) L"Small blocks (512 KB)");
|
||||
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE, 0);
|
||||
|
||||
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE);
|
||||
settings_show_window(hdlg, IDT_1775, FALSE);
|
||||
|
||||
if (existing & 1) {
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE);
|
||||
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE);
|
||||
settings_show_window(hdlg, IDC_COMBO_HD_IMG_FORMAT, FALSE);
|
||||
settings_show_window(hdlg, IDT_1774, FALSE);
|
||||
|
||||
/* adjust window size */
|
||||
GetWindowRect(hdlg, &rect);
|
||||
OffsetRect(&rect, -rect.left, -rect.top);
|
||||
dlg_height_adjust = rect.bottom / 5;
|
||||
SetWindowPos(hdlg, NULL, 0, 0, rect.right, rect.bottom - dlg_height_adjust, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER);
|
||||
h = GetDlgItem(hdlg, IDOK);
|
||||
GetWindowRect(h, &rect);
|
||||
point.x = rect.left;
|
||||
point.y = rect.top;
|
||||
ScreenToClient(hdlg, &point);
|
||||
SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER);
|
||||
h = GetDlgItem(hdlg, IDCANCEL);
|
||||
GetWindowRect(h, &rect);
|
||||
point.x = rect.left;
|
||||
point.y = rect.top;
|
||||
ScreenToClient(hdlg, &point);
|
||||
SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER);
|
||||
|
||||
chs_enabled = 0;
|
||||
} else
|
||||
chs_enabled = 1;
|
||||
|
||||
add_locations(hdlg);
|
||||
hdd_ptr->bus = HDD_BUS_IDE;
|
||||
max_spt = 63;
|
||||
@@ -2502,19 +2723,22 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
|
||||
memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn));
|
||||
wcscpy(hdd_ptr->fn, hd_file_name);
|
||||
wcstombs(hd_file_name_multibyte, hd_file_name, sizeof hd_file_name_multibyte);
|
||||
|
||||
sector_size = 512;
|
||||
|
||||
if (!(existing & 1) && (wcslen(hd_file_name) > 0)) {
|
||||
f = _wfopen(hd_file_name, L"wb");
|
||||
|
||||
if (size > 0x1FFFFFFE00ll) {
|
||||
fclose(f);
|
||||
if (size > 0x1FFFFFFE00ll) {
|
||||
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4105);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (image_is_hdi(hd_file_name)) {
|
||||
img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT);
|
||||
if (img_format < 3) {
|
||||
f = _wfopen(hd_file_name, L"wb");
|
||||
}
|
||||
|
||||
if (img_format == 1) { /* HDI file */
|
||||
if (size >= 0x100000000ll) {
|
||||
fclose(f);
|
||||
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104);
|
||||
@@ -2532,7 +2756,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
|
||||
for (i = 0; i < 0x3f8; i++)
|
||||
fwrite(&zero, 1, 4, f);
|
||||
} else if (image_is_hdx(hd_file_name, 0)) {
|
||||
} else if (img_format == 2) { /* HDX file */
|
||||
fwrite(&signature, 1, 8, f); /* 00000000: Signature */
|
||||
fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */
|
||||
fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */
|
||||
@@ -2541,12 +2765,39 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */
|
||||
fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */
|
||||
fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */
|
||||
}
|
||||
} else if (img_format >= 3) { /* VHD file */
|
||||
MVHDGeom _86box_geometry;
|
||||
block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL;
|
||||
switch (img_format) {
|
||||
case 3:
|
||||
vhd_progress_hdlg = hdlg;
|
||||
_86box_geometry = create_drive_vhd_fixed(hd_file_name_multibyte, tracks, hpc, spt);
|
||||
break;
|
||||
case 4:
|
||||
_86box_geometry = create_drive_vhd_dynamic(hd_file_name_multibyte, tracks, hpc, spt, block_size);
|
||||
break;
|
||||
case 5:
|
||||
if (file_dlg_w(hdlg, L"VHD files (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0", L"", L"Select the parent VHD",0)) {
|
||||
return TRUE;
|
||||
}
|
||||
_86box_geometry = create_drive_vhd_diff(hd_file_name_multibyte, openfilestring, block_size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (img_format != 5)
|
||||
settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117);
|
||||
|
||||
hdd_ptr->tracks = _86box_geometry.cyl;
|
||||
hdd_ptr->hpc = _86box_geometry.heads;
|
||||
hdd_ptr->spt = _86box_geometry.spt;
|
||||
|
||||
hard_disk_added = 1;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
big_buf = (char *) malloc(1048576);
|
||||
memset(big_buf, 0, 1048576);
|
||||
|
||||
temp_size = size;
|
||||
memset(big_buf, 0, 1048576);
|
||||
|
||||
r = size >> 20;
|
||||
size &= 0xfffff;
|
||||
@@ -2580,12 +2831,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image_is_vhd(hd_file_name, 0)) {
|
||||
/* VHD image. */
|
||||
// Create VHD image here of size temp_size bytes.
|
||||
}
|
||||
}
|
||||
|
||||
free(big_buf);
|
||||
|
||||
@@ -2603,8 +2849,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDC_CFILE:
|
||||
if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", !(existing & 1))) {
|
||||
case IDC_CFILE:
|
||||
if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", NULL, !(existing & 1))) {
|
||||
if (!wcschr(wopenfilestring, L'.')) {
|
||||
if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) {
|
||||
twcs = &wopenfilestring[wcslen(wopenfilestring)];
|
||||
@@ -2645,7 +2891,39 @@ hdd_add_file_open_error:
|
||||
fread(&hpc, 1, 4, f);
|
||||
fread(&tracks, 1, 4, f);
|
||||
} else if (image_is_vhd(wopenfilestring, 1)) {
|
||||
// Read VHD geometry
|
||||
fclose(f);
|
||||
wcstombs(hd_file_name_multibyte, wopenfilestring, sizeof hd_file_name_multibyte);
|
||||
MVHDMeta* vhd = mvhd_open(hd_file_name_multibyte, 0, &vhd_error);
|
||||
if (vhd == NULL) {
|
||||
settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108);
|
||||
return TRUE;
|
||||
} else if (vhd_error == MVHD_ERR_TIMESTAMP) {
|
||||
wchar_t* ts_warning =
|
||||
L"WARNING: VHD PARENT/CHILD TIMESTAMPS DO NOT MATCH!\n\n"
|
||||
"This could indicate that the parent image was modified after this VHD was created.\n\n"
|
||||
"This could also happen if the VHD files were moved/copied, or the differencing VHD was created with DiskPart.\n\n"
|
||||
"Do you wish to fix this error after a file copy or DiskPart creation?";
|
||||
if (settings_msgbox_ex(MBX_QUESTION_YN, L"VHD Timestamp Mismatch", ts_warning, NULL, NULL, NULL) != 0) {
|
||||
int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhd_error);
|
||||
if (ts_res != 0)
|
||||
{
|
||||
settings_msgbox_header(MBX_ERROR, L"Error", L"Could not fix VHD timestamp.");
|
||||
mvhd_close(vhd);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
mvhd_close(vhd);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
MVHDGeom vhd_geom = mvhd_get_geometry(vhd);
|
||||
adjust_vhd_geometry_for_86box(&vhd_geom);
|
||||
tracks = vhd_geom.cyl;
|
||||
hpc = vhd_geom.heads;
|
||||
spt = vhd_geom.spt;
|
||||
size = (uint64_t)tracks * hpc * spt * 512;
|
||||
mvhd_close(vhd);
|
||||
} else {
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
size = ftello64(f);
|
||||
@@ -2951,6 +3229,51 @@ hdd_add_file_open_error:
|
||||
|
||||
no_update = 0;
|
||||
break;
|
||||
case IDC_COMBO_HD_IMG_FORMAT:
|
||||
img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT);
|
||||
|
||||
no_update = 1;
|
||||
if (img_format == 5) { /* They switched to a diff VHD; disable the geometry fields. */
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE);
|
||||
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, L"(N/A)");
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE);
|
||||
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_HPC, L"(N/A)");
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE);
|
||||
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_CYL, L"(N/A)");
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE);
|
||||
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SIZE, L"(N/A)");
|
||||
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE);
|
||||
settings_reset_content(hdlg, IDC_COMBO_HD_TYPE);
|
||||
settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) L"(use parent)");
|
||||
settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, 0);
|
||||
} else {
|
||||
get_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, text_buf, 256);
|
||||
if (!wcscmp(text_buf, L"(N/A)")) {
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE);
|
||||
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE);
|
||||
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, 15);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE);
|
||||
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, 1023);
|
||||
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE);
|
||||
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) ((uint64_t)17 * 15 * 1023 * 512 >> 20));
|
||||
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE);
|
||||
hdconf_initialize_hdt_combo(hdlg);
|
||||
}
|
||||
}
|
||||
no_update = 0;
|
||||
|
||||
if (img_format == 4 || img_format == 5) /* For dynamic and diff VHDs, show the block size dropdown. */
|
||||
{
|
||||
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, TRUE);
|
||||
settings_show_window(hdlg, IDT_1775, TRUE);
|
||||
}
|
||||
else /* Hide it otherwise. */
|
||||
{
|
||||
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE);
|
||||
settings_show_window(hdlg, IDT_1775, FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
Reference in New Issue
Block a user