uae_u32 block, flags;
uae_u8 buf[512];
TCHAR dt[32];
+ uae_u32 error = 0;
flags = rl (pp + 20);
pp[37 + pp[36]] = 0;
write_log (_T("Empty drive\n"));
} else {
block = lowcyl * surfaces * spt;
- if (hdf_read (hfd, buf, (uae_u64)blocksize * block, sizeof buf)) {
+ if (hdf_read (hfd, buf, (uae_u64)blocksize * block, sizeof buf, &error)) {
write_log (_T("First block %d dostype: %08X (%s)\n"), block, rl (buf), dostypes (dt, rl (buf)));
} else {
write_log (_T("First block %d read failed!\n"), block);
static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, uae_u8 *buf, int readblocksize)
{
TCHAR dt[32];
+ uae_u32 error = 0;
write_log (_T("RDB: HostID: %08x Flags: %08x\n"),
rl (bufrdb + 3 * 4), rl (bufrdb + 5 * 4));
break;
}
memset (buf, 0, readblocksize);
- hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize);
+ hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("PART", buf, partblock)) {
write_log (_T("RDB: checksum error PART block %d\n"), partblock);
dumprdbblock(buf, partblock);
break;
}
memset (buf, 0, readblocksize);
- hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize);
+ hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("FSHD", buf, fileblock)) {
write_log (_T("RDB: checksum error FSHD block %d\n"), fileblock);
dumprdbblock(buf, fileblock);
struct hardfiledata *hfd = &uip->hf;
struct uaedev_config_info *ci = &uip[unit_no].hf.ci;
uae_u32 bad;
+ uae_u32 error = 0;
uae_u32 bs = (bufrdb[0x20] << 24) | (bufrdb[0x21] << 16) | (bufrdb[0x22] << 8) | (bufrdb[0x23] << 0);
int bscnt;
if (bad) {
if (bad * hfd->ci.blocksize > FILESYS_MAX_BLOCKSIZE)
return 0;
- hdf_read_rdb(hfd, bufrdb2, bad * hfd->ci.blocksize, hfd->ci.blocksize);
+ hdf_read_rdb(hfd, bufrdb2, bad * hfd->ci.blocksize, hfd->ci.blocksize, &error);
if (bufrdb2[0] != 0xBA || bufrdb2[1] != 0xD1)
return 0;
}
TCHAR *s;
bool showdebug = partnum == 0;
int cnt;
+ uae_u32 error = 0;
blocksize = rl (bufrdb + 16);
readblocksize = blocksize > hfd->ci.blocksize ? blocksize : hfd->ci.blocksize;
goto error;
}
memset (buf, 0, readblocksize);
- hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize);
+ hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("PART", buf, partblock)) {
err = -2;
write_log(_T("RDB: checksum error in PART block %d\n"), partblock);
goto error;
}
memset (buf, 0, readblocksize);
- hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize);
+ hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("FSHD", buf, fileblock)) {
write_log (_T("RDB: checksum error in FSHD block %d\n"), fileblock);
dumprdbblock(buf, fileblock);
if (!legalrdbblock (uip, lsegblock))
goto error;
memset (buf, 0, readblocksize);
- hdf_read (hfd, buf, lsegblock * hfd->ci.blocksize, readblocksize);
+ hdf_read (hfd, buf, lsegblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum("LSEG", buf, lsegblock)) {
write_log(_T("RDB: checksum error in LSEG block %d\n"), lsegblock);
dumprdbblock(buf, lsegblock);
struct hardfiledata *hfd = &uip->hf;
int lastblock = 63, rdblock;
uae_u8 bufrdb[FILESYS_MAX_BLOCKSIZE];
+ uae_u32 error = 0;
write_log (_T("%s:\n"), uip->rootdir);
if (hfd->drive_empty) {
}
for (rdblock = 0; rdblock < lastblock; rdblock++) {
- hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
- if (rdblock == 0 && bufrdb[0] == 0xBA && bufrdb[1] == 0xBE) {
+ hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize, &error);
+ if (!error && rdblock == 0 && bufrdb[0] == 0xBA && bufrdb[1] == 0xBE) {
// A2090 "BABE" partition table?
int v = pt_babe(ctx, bufrdb, uip, unit_no, partnum, parmpacket);
if (v)
return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
}
if (!memcmp ("RDSK", bufrdb, 4)) {
+ uae_u32 error = 0;
bufrdb[0xdc] = 0;
bufrdb[0xdd] = 0;
bufrdb[0xde] = 0;
bufrdb[0xdf] = 0;
if (rdb_checksum ("RDSK", bufrdb, rdblock)) {
write_log (_T("Windows 95/98/ME trashed RDB detected, fixing..\n"));
- hdf_write (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
+ hdf_write (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize, &error);
return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
}
}
int ver = -1, rev = -1;
uae_u32 dostype;
bool autofs = false;
+ uae_u32 error = 0;
// we already have custom filesystem loaded for earlier hardfile?
if (!ci->forceload) {
if (!ci->dostype) {
memset (buf, 0, 4);
- hdf_read (&uip->hf, buf, 0, 512);
+ hdf_read (&uip->hf, buf, 0, 512, &error);
dostype = (buf[0] << 24) | (buf[1] << 16) |(buf[2] << 8) | buf[3];
} else {
dostype = ci->dostype;
int unit_no = no & 65535;
int sub_no = no >> 16;
int type;
+ uae_u32 error = 0;
if (unit_no >= MAX_FILESYSTEM_UNITS)
return -2;
memset(buf, 0, sizeof buf);
if (ci->dostype) { // forced dostype?
trap_put_long(ctx, parmpacket + 80, ci->dostype); /* dostype */
- } else if (hdf_read (&uip[unit_no].hf, buf, 0, sizeof buf)) {
+ } else if (hdf_read (&uip[unit_no].hf, buf, 0, sizeof buf, &error)) {
uae_u32 dt = rl (buf);
if (dt != 0x00000000 && dt != 0xffffffff)
trap_put_long(ctx, parmpacket + 80, dt);
uae_u8 block[512];
int i;
uae_u64 minsize = 512 * 1024 * 1024;
+ uae_u32 error = 0;
if (size <= minsize) {
*phead = 1;
}
memset (block, 0, sizeof block);
if (hfd) {
- hdf_read(hfd, block, 0, 512);
- if (block[0] == 'D' && block[1] == 'O' && block[2] == 'S') {
+ hdf_read(hfd, block, 0, 512, &error);
+ if (!error && block[0] == 'D' && block[1] == 'O' && block[2] == 'S') {
int mode;
for (mode = 0; mode < 2; mode++) {
uae_u32 rootblock;
getchsgeometry2 (size, pcyl, phead, psectorspertrack, mode);
rootblock = (2 + ((*pcyl) * (*phead) * (*psectorspertrack) - 1)) / 2;
memset (block, 0, sizeof block);
- hdf_read(hfd, block, (uae_u64)rootblock * 512, 512);
+ hdf_read(hfd, block, (uae_u64)rootblock * 512, 512, &error);
for (i = 0; i < 512; i += 4)
chk += (block[i] << 24) | (block[i + 1] << 16) | (block[i + 2] << 8) | (block[i + 3] << 0);
if (!chk && block[0] == 0 && block[1] == 0 && block[2] == 0 && block[3] == 2 &&
int hdf_hd_open (struct hd_hardfiledata *hfd)
{
struct uaedev_config_info *ci = &hfd->hfd.ci;
+ uae_u32 error = 0;
+
if (hdf_open (&hfd->hfd) <= 0)
return 0;
hfd->hfd.unitnum = ci->uae_unitnum;
hfd->heads_def = hfd->heads;
if (ci->surfaces && ci->sectors) {
uae_u8 buf[512] = { 0 };
- hdf_read (&hfd->hfd, buf, 0, 512);
- if (buf[0] != 0 && memcmp (buf, _T("RDSK"), 4)) {
+ hdf_read (&hfd->hfd, buf, 0, 512, &error);
+ if (!error && buf[0] != 0 && memcmp (buf, _T("RDSK"), 4)) {
ci->highcyl = (int)((hfd->hfd.virtsize / ci->blocksize) / (ci->sectors * ci->surfaces));
ci->dostype = rl (buf);
create_virtual_rdb (&hfd->hfd);
return ~sum;
}
-static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
-static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
+static int hdf_write2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
+static int hdf_read2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
-static void hdf_init_cache (struct hardfiledata *hfd)
+static void hdf_init_cache(struct hardfiledata *hfd)
{
}
-static void hdf_flush_cache (struct hardfiledata *hdf)
+static void hdf_flush_cache(struct hardfiledata *hdf)
{
}
-static int hdf_cache_read (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_cache_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
- return hdf_read2 (hfd, buffer, offset, len);
+ return hdf_read2(hfd, buffer, offset, len, error);
}
-static int hdf_cache_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_cache_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
- return hdf_write2 (hfd, buffer, offset, len);
+ return hdf_write2(hfd, buffer, offset, len, error);
}
int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
uae_u8 tmp[512], tmp2[512];
uae_u32 v;
TCHAR filepath[MAX_DPATH];
+ uae_u32 error = 0;
if ((!pname || pname[0] == 0) && hfd->ci.rootdir[0] == 0)
return 0;
ret = hdf_open_target (hfd, filepath);
if (ret <= 0)
return ret;
- if (hdf_read_target (hfd, tmp, 0, 512) != 512)
+ if (hdf_read_target (hfd, tmp, 0, 512, &error) != 512)
goto nonvhd;
v = gl (tmp + 8); // features
if ((v & 3) != 2)
goto nonvhd;
if (vhd_checksum (tmp, 8 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 4) != v)
goto nonvhd;
- if (hdf_read_target (hfd, tmp2, hfd->physsize - sizeof tmp2, 512) != 512)
+ if (hdf_read_target (hfd, tmp2, hfd->physsize - sizeof tmp2, 512, &error) != 512)
goto end;
if (memcmp (tmp, tmp2, sizeof tmp))
goto nonvhd;
hfd->vhd_bamoffset = gl (tmp + 8 + 4 + 4 + 4);
if (hfd->vhd_bamoffset == 0 || hfd->vhd_bamoffset >= hfd->physsize)
goto end;
- if (hdf_read_target (hfd, tmp, hfd->vhd_bamoffset, 512) != 512)
+ if (hdf_read_target (hfd, tmp, hfd->vhd_bamoffset, 512, &error) != 512)
goto end;
v = gl (tmp + 8 + 8 + 8 + 4 + 4 + 4);
if (vhd_checksum (tmp, 8 + 8 + 8 + 4 + 4 + 4) != v)
hfd->vhd_bamsize = (((hfd->virtsize + hfd->vhd_blocksize - 1) / hfd->vhd_blocksize) * 4 + 511) & ~511;
size = hfd->vhd_bamoffset + hfd->vhd_bamsize;
hfd->vhd_header = xmalloc (uae_u8, size);
- if (hdf_read_target (hfd, hfd->vhd_header, 0, size) != size)
+ if (hdf_read_target (hfd, hfd->vhd_header, 0, size, &error) != size)
goto end;
hfd->vhd_sectormap = xmalloc (uae_u8, 512);
hfd->vhd_sectormapblock = -1;
{
uae_u64 read;
uae_u8 *dataptr = (uae_u8*)v;
+ uae_u32 error = 0;
//write_log (_T("%08x %08x\n"), (uae_u32)offset, (uae_u32)len);
read = 0;
if (hfd->vhd_sectormapblock != sectormapblock) {
// read sector bitmap
//write_log (_T("BM %08x\n"), sectormapblock);
- if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
+ if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_read: bitmap read error\n"));
return read;
}
// read data block
uae_u64 block = sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512;
//write_log (_T("DB %08x\n"), block);
- if (hdf_read_target (hfd, dataptr, block, 512) != 512) {
+ if (hdf_read_target (hfd, dataptr, block, 512, &error) != 512) {
write_log (_T("vhd_read: data read error\n"));
return read;
}
{
uae_u8 *buf, *p;
int len;
- uae_u32 block;
+ uae_u32 block, error = 0;
int v;
len = hfd->vhd_blocksize + hfd->vhd_bitmapsize + 512;
}
// add footer (same as 512 byte header)
memcpy (buf + len - 512, hfd->vhd_header, 512);
- v = hdf_write_target (hfd, buf, hfd->vhd_footerblock, len);
+ v = hdf_write_target (hfd, buf, hfd->vhd_footerblock, len, &error);
xfree (buf);
if (v != len) {
write_log (_T("vhd_enlarge: footer write error\n"));
p[2] = block >> 8;
p[3] = block >> 0;
// write to disk
- if (hdf_write_target (hfd, hfd->vhd_header + hfd->vhd_bamoffset, hfd->vhd_bamoffset, hfd->vhd_bamsize) != hfd->vhd_bamsize) {
+ if (hdf_write_target (hfd, hfd->vhd_header + hfd->vhd_bamoffset, hfd->vhd_bamoffset, hfd->vhd_bamsize, &error) != hfd->vhd_bamsize) {
write_log (_T("vhd_enlarge: bam write error\n"));
return 0;
}
{
uae_u64 written;
uae_u8 *dataptr = (uae_u8*)v;
+ uae_u32 error = 0;
//write_log (_T("%08x %08x\n"), (uae_u32)offset, (uae_u32)len);
written = 0;
uae_u64 sectormapblock = sectoroffset * (uae_u64)512 + (bitmapoffsetbytes & ~511);
if (hfd->vhd_sectormapblock != sectormapblock) {
// read sector bitmap
- if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
+ if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_write: bitmap read error\n"));
return written;
}
hfd->vhd_sectormapblock = sectormapblock;
}
// write data
- if (hdf_write_target (hfd, dataptr, sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512, 512) != 512) {
+ if (hdf_write_target (hfd, dataptr, sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512, 512, &error) != 512) {
write_log (_T("vhd_write: data write error\n"));
return written;
}
if (!(hfd->vhd_sectormap[bitmapoffsetbytes & 511] & (1 << (7 - (bitmapoffsetbits & 7))))) {
// no, we need to mark it allocated and write the modified bitmap back to the disk
hfd->vhd_sectormap[bitmapoffsetbytes & 511] |= (1 << (7 - (bitmapoffsetbits & 7)));
- if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
+ if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_write: bam write error\n"));
return written;
}
return ret;
}
-static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_read2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int ret = 0, extra = 0;
+
if (offset < hfd->virtual_size) {
uae_s64 len2 = offset + len <= hfd->virtual_size ? len : hfd->virtual_size - offset;
if (len > INT_MAX) {
if (hfd->hfd_type == HFD_VHD_DYNAMIC)
ret = (int)vhd_read (hfd, buffer, offset, len);
else if (hfd->hfd_type == HFD_VHD_FIXED)
- ret = hdf_read_target (hfd, buffer, offset + 512, len);
+ ret = hdf_read_target (hfd, buffer, offset + 512, len, error);
#ifdef WITH_CHD
else if (hfd->hfd_type == HFD_CHD_OTHER) {
chd_file *cf = (chd_file*)hfd->chd_handle;
}
#endif
else
- ret = hdf_read_target (hfd, buffer, offset, len);
+ ret = hdf_read_target (hfd, buffer, offset, len, error);
if (ret <= 0)
return ret;
return ret;
}
-static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_write2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
if (len > INT_MAX)
return 0;
offset -= hfd->virtual_size;
if (hfd->hfd_type == HFD_VHD_DYNAMIC)
- ret = (int)vhd_write (hfd, buffer, offset, len);
+ ret = (int)vhd_write(hfd, buffer, offset, len);
else if (hfd->hfd_type == HFD_VHD_FIXED)
- ret = hdf_write_target (hfd, buffer, offset + 512, len);
+ ret = hdf_write_target(hfd, buffer, offset + 512, len, error);
#ifdef WITH_CHD
else if (hfd->hfd_type == HFD_CHD_OTHER)
return 0;
}
#endif
else
- ret = hdf_write_target (hfd, buffer, offset, len);
+ ret = hdf_write_target(hfd, buffer, offset, len, error);
if (ret <= 0)
return ret;
}
}
-int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
- v = hdf_read (hfd, buffer, offset, len);
+ v = hdf_read (hfd, buffer, offset, len, error);
if (v > 0 && offset < 16 * 512 && !hfd->byteswap && !hfd->adide) {
uae_u8 *buf = (uae_u8*)buffer;
bool changed = false;
write_log (_T("HDF: byteswapped RDB detected\n"));
}
if (changed)
- v = hdf_read (hfd, buffer, offset, len);
+ v = hdf_read (hfd, buffer, offset, len, error);
}
return v;
}
-int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
+ uae_u32 error2 = 0;
+
+ if (error) {
+ *error = 0;
+ } else {
+ error = &error2;
+ }
- hf_log3 (_T("cmd_read: %p %04x-%08x (%d) %08x (%d)\n"),
+ hf_log3(_T("cmd_read: %p %04x-%08x (%d) %08x (%d)\n"),
buffer, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->ci.blocksize), (uae_u32)len, (uae_u32)(len / hfd->ci.blocksize));
if (!hfd->adide) {
- v = hdf_cache_read (hfd, buffer, offset, len);
+ v = hdf_cache_read(hfd, buffer, offset, len, error);
} else {
offset += 512;
- v = hdf_cache_read (hfd, buffer, offset, len);
- adide_decode (buffer, len);
+ v = hdf_cache_read(hfd, buffer, offset, len, error);
+ adide_decode(buffer, len);
}
if (hfd->byteswap)
- hdf_byteswap (buffer, len);
+ hdf_byteswap(buffer, len);
return v;
}
-int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
- hf_log3 (_T("cmd_write: %p %04x-%08x (%d) %08x (%d)\n"),
+ uae_u32 error2 = 0;
+
+ if (error) {
+ *error = 0;
+ } else {
+ error = &error2;
+ }
+
+ hf_log3(_T("cmd_write: %p %04x-%08x (%d) %08x (%d)\n"),
buffer, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->ci.blocksize), (uae_u32)len, (uae_u32)(len / hfd->ci.blocksize));
if (hfd->byteswap)
- hdf_byteswap (buffer, len);
+ hdf_byteswap(buffer, len);
if (!hfd->adide) {
- v = hdf_cache_write (hfd, buffer, offset, len);
+ v = hdf_cache_write(hfd, buffer, offset, len, error);
} else {
offset += 512;
- adide_encode (buffer, len);
- v = hdf_cache_write (hfd, buffer, offset, len);
- adide_decode (buffer, len);
+ adide_encode(buffer, len);
+ v = hdf_cache_write(hfd, buffer, offset, len, error);
+ adide_decode(buffer, len);
}
if (hfd->byteswap)
- hdf_byteswap (buffer, len);
+ hdf_byteswap(buffer, len);
return v;
}
-static uae_u64 cmd_readx(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
+static uae_u64 cmd_readx(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
m68k_cancel_idle();
- gui_flicker_led (LED_HD, hfd->unitnum, 1);
- return hdf_read (hfd, dataptr, offset, (int)len);
+ gui_flicker_led(LED_HD, hfd->unitnum, 1);
+ return hdf_read(hfd, dataptr, offset, (int)len, error);
}
-static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
+static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
return 0;
if (bank_data->check(dataptr, (uae_u32)len)) {
uae_u8 *buffer = bank_data->xlateaddr(dataptr);
- return cmd_readx(hfd, buffer, offset, (uae_u32)len);
+ return cmd_readx(hfd, buffer, offset, (uae_u32)len, error);
}
}
int total = 0;
uae_u8 buf[RTAREA_TRAP_DATA_EXTRA_SIZE];
int max = RTAREA_TRAP_DATA_EXTRA_SIZE & ~511;
int size = (int)(len > max ? max : len);
- if (cmd_readx(hfd, buf, offset, size) != size)
+ if (cmd_readx(hfd, buf, offset, size, error) != size)
break;
trap_put_bytes(ctx, buf, dataptr, size);
offset += size;
}
return total;
}
-static uae_u64 cmd_writex(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
+static uae_u64 cmd_writex(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
m68k_cancel_idle();
- gui_flicker_led (LED_HD, hfd->unitnum, 2);
- return hdf_write (hfd, dataptr, offset, (uae_u32)len);
+ gui_flicker_led(LED_HD, hfd->unitnum, 2);
+ return hdf_write(hfd, dataptr, offset, (uae_u32)len, error);
}
-static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
+static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
return 0;
if (bank_data->check(dataptr, (uae_u32)len)) {
uae_u8 *buffer = bank_data->xlateaddr(dataptr);
- return cmd_writex(hfd, buffer, offset, len);
+ return cmd_writex(hfd, buffer, offset, len, error);
}
}
int total = 0;
int max = RTAREA_TRAP_DATA_EXTRA_SIZE & ~511;
int size = (int)(len > max ? max : len);
trap_get_bytes(ctx, buf, dataptr, size);
- if (cmd_writex(hfd, buf, offset, size) != size)
+ if (cmd_writex(hfd, buf, offset, size, error) != size)
break;
offset += size;
dataptr += size;
bool omti = hfd->ci.unit_feature_level == HD_LEVEL_SASI_CHS;
uae_u8 sasi_sense = 0;
uae_u64 current_lba = ~0;
+ uae_u32 error = 0;
cmd = cmdbuf[0];
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 1;
+ goto checkfail;
+ }
break;
case 0x0e: /* READ SECTOR BUFFER */
len = hfd->ci.blocksize;
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 2;
+ goto checkfail;
+ }
break;
case 0x55: // MODE SELECT(10)
case 0x15: // MODE SELECT(6)
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 1;
+ goto checkfail;
+ }
break;
case 0x2a: /* WRITE (10) */
if (nodisk (hfd))
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 2;
+ goto checkfail;
+ }
break;
case 0x2f: /* VERIFY (10) */
{
goto checkfail;
uae_u8 *vb = xmalloc(uae_u8, hfd->ci.blocksize);
while (len > 0) {
- uae_u64 readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize);
+ uae_u64 readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize, &error);
+ if (error) {
+ chkerr = 1;
+ goto checkfail;
+ }
if (readlen != hfd->ci.blocksize || memcmp (vb, scsi_data, hfd->ci.blocksize)) {
xfree (vb);
goto miscompare;
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 1;
+ goto checkfail;
+ }
break;
case 0xaa: /* WRITE (12) */
if (nodisk (hfd))
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
- scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+ scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len, &error);
+ if (error) {
+ chkerr = 2;
+ goto checkfail;
+ }
break;
case 0x37: /* READ DEFECT DATA */
if (nodisk (hfd))
if (isbadblock(hfd, offset, len)) {
goto bad_block;
}
- actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset, len);
+ actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset, len, &error);
break;
#if HDF_SUPPORT_TD64
if (isbadblock(hfd, offset64, len)) {
goto bad_block;
}
- actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset64, len);
+ actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset64, len, &error);
break;
#endif
if (isbadblock(hfd, offset, len)) {
goto bad_block;
}
- actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset, len);
+ actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset, len, &error);
}
break;
if (isbadblock(hfd, offset64, len)) {
goto bad_block;
}
- actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset64, len);
+ actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset64, len, &error);
}
break;
#endif
_tcscpy (devname, udi->device_name + 1);
- if (devname[0] == ':' && devname[1] == 'P' && devname[2] == '#' &&
- (devname[4] == '_' || devname[5] == '_')) {
- TCHAR c1 = devname[3];
- TCHAR c2 = devname[4];
+ TCHAR *n = udi->device_name;
+ if (n[0] == ':' && n[1] == 'P' && n[2] == '#' &&
+ (n[4] == '_' || n[5] == '_')) {
+ TCHAR c1 = n[3];
+ TCHAR c2 = n[4];
if (c1 >= '0' && c1 <= '9') {
amipart = c1 - '0';
if (c2 != '_') {
if (!hfd->ci.lock)
return;
+ if (hfd->flags & HFD_FLAGS_REALDRIVEPARTITION)
+ return;
// single partition FAT drives seem to lock this way, without need for administrator privileges
if (DeviceIoControl(drvhandle, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &written, NULL)) {
hfd->handle->h = INVALID_HANDLE_VALUE;
hfd_log (_T("hfd attempting to open: '%s'\n"), name);
if (name[0] == ':') {
+ DWORD rw = GENERIC_READ;
+ DWORD srw = FILE_SHARE_READ;
int drvnum = -1;
TCHAR *p = _tcschr (name + 1, ':');
if (p) {
+ // open partitions in shared read/write mode
+ if (name[0] ==':' && name[1] == 'P') {
+ rw |= GENERIC_WRITE;
+ srw |= FILE_SHARE_WRITE;
+ }
*p++ = 0;
// do not scan for drives if open succeeds and it is a harddrive
// to prevent spinup of sleeping drives
- h = CreateFile (p,
- GENERIC_READ,
- FILE_SHARE_READ,
+ h = CreateFile (p, rw, srw,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
DWORD err = GetLastError ();
if (h == INVALID_HANDLE_VALUE && err == ERROR_FILE_NOT_FOUND) {
flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS;
h = CreateFile (udi->device_path,
- GENERIC_READ | (hfd->ci.readonly && !chs ? 0 : GENERIC_WRITE),
- FILE_SHARE_READ | (hfd->ci.readonly && !chs ? 0 : FILE_SHARE_WRITE),
+ rw | (hfd->ci.readonly && !chs ? 0 : GENERIC_WRITE),
+ srw | (hfd->ci.readonly && !chs ? 0 : FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, flags, NULL);
hfd->handle->h = h;
if (h == INVALID_HANDLE_VALUE && !hfd->ci.readonly) {
return 1;
}
-static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset)
+static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset, bool write)
{
DWORD ret;
if (offset >= hfd->physsize - hfd->virtual_size) {
if (hfd->virtual_rdb)
return -1;
- gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
- abort ();
+ if (write) {
+ gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
+ abort ();
+ }
+ write_log(_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
+ return -1;
}
offset += hfd->offset;
if (offset & (hfd->ci.blocksize - 1)) {
- gui_message (_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
+ if (write) {
+ gui_message (_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
+ offset, hfd->ci.blocksize, offset, hfd->ci.blocksize, offset & (hfd->ci.blocksize - 1));
+ abort ();
+ }
+ write_log(_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
offset, hfd->ci.blocksize, offset, hfd->ci.blocksize, offset & (hfd->ci.blocksize - 1));
- abort ();
+ return -1;
}
}
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
size = bs - soff;
if (size > len)
size = len;
- hdf_seek (hfd, offset & ~mask);
+ hdf_seek (hfd, offset & ~mask, dowrite != 0);
poscheck (hfd, len);
if (dowrite)
WriteFile (hfd->handle, hfd->cache, bs, &outlen2, NULL);
len -= size;
}
while (len >= bs) { /* aligned access */
- hdf_seek (hfd, offset);
+ hdf_seek (hfd, offset, dowrite != 0);
poscheck (hfd, len);
size = len & ~mask;
if (size > CACHE_SIZE)
len -= size;
}
if (len > 0) { /* len > 0 && len < bs */
- hdf_seek (hfd, offset);
+ hdf_seek (hfd, offset, dowrite != 0);
poscheck (hfd, len);
if (dowrite)
WriteFile (hfd->handle, hfd->cache, bs, &outlen2, NULL);
#else
-static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_read_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
DWORD outlen = 0;
int coffset;
- if (offset == 0)
+ if (len == 0) {
+ return 0;
+ }
+ if (offset == 0) {
hfd->cache_valid = 0;
+ }
coffset = isincache (hfd, offset, len);
if (coffset >= 0) {
memcpy (buffer, hfd->cache + coffset, len);
hfd->cache_offset = offset;
if (offset + CACHE_SIZE > hfd->offset + (hfd->physsize - hfd->virtual_size))
hfd->cache_offset = hfd->offset + (hfd->physsize - hfd->virtual_size) - CACHE_SIZE;
- if (hdf_seek(hfd, hfd->cache_offset))
+ if (hdf_seek(hfd, hfd->cache_offset, false)) {
+ *error = 45;
return 0;
+ }
poscheck (hfd, CACHE_SIZE);
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
ReadFile(hfd->handle->h, hfd->cache, CACHE_SIZE, &outlen, NULL);
outlen = (DWORD)zfile_fread(hfd->cache, 1, CACHE_SIZE, hfd->handle->zf);
}
hfd->cache_valid = 0;
- if (outlen != CACHE_SIZE)
+ if (outlen != CACHE_SIZE) {
+ *error = 45;
return 0;
+ }
hfd->cache_valid = 1;
coffset = isincache (hfd, offset, len);
if (coffset >= 0) {
}
write_log (_T("hdf_read: cache bug! offset=%I64d len=%d\n"), offset, len);
hfd->cache_valid = 0;
+ *error = 45;
return 0;
}
-int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+int hdf_read_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int got = 0;
uae_u8 *p = (uae_u8*)buffer;
+ uae_u32 error2 = 0;
- if (hfd->drive_empty)
+ if (error) {
+ *error = 0;
+ } else {
+ error = &error2;
+ }
+
+ if (hfd->drive_empty) {
+ *error = 29;
return 0;
+ }
if (hfd->handle_valid == HDF_HANDLE_WIN32_CHS) {
int len2 = len;
DWORD ret;
if (hfd->physsize < CACHE_SIZE) {
hfd->cache_valid = 0;
- if (hdf_seek(hfd, offset))
+ if (hdf_seek(hfd, offset, false))
return got;
if (hfd->physsize)
poscheck (hfd, len);
maxlen = len;
} else {
maxlen = len > CACHE_SIZE ? CACHE_SIZE : len;
- ret = hdf_read_2 (hfd, p, offset, maxlen);
+ ret = hdf_read_2 (hfd, p, offset, maxlen, error);
}
got += ret;
if (ret != maxlen)
return got;
}
-static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+static int hdf_write_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
DWORD outlen = 0;
- if (hfd->ci.readonly)
+ if (hfd->ci.readonly) {
+ *error = 28;
return 0;
- if (hfd->dangerous)
+ }
+ if (hfd->dangerous) {
+ *error = 28;
return 0;
+ }
if (len == 0)
return 0;
hfd->cache_valid = 0;
- if (hdf_seek(hfd, offset))
+ if (hdf_seek(hfd, offset, true)) {
+ *error = 45;
return 0;
+ }
poscheck (hfd, len);
memcpy (hfd->cache, buffer, len);
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
if (ismounted (hfd->ci.devname, hfd->handle->h)) {
gui_message (_T("\"%s\"\n\nBlock zero write attempt but drive has one or more mounted PC partitions or WinUAE does not have Administrator privileges. Erase the drive or unmount all PC partitions first."), name);
hfd->ci.readonly = true;
+ *error = 45;
return 0;
}
}
}
WriteFile (hfd->handle->h, hfd->cache, len, &outlen, NULL);
+ if (outlen != len) {
+ *error = 45;
+ }
if (offset == 0) {
+ DWORD err = GetLastError();
DWORD outlen2;
uae_u8 *tmp;
int tmplen = 512;
if (tmp) {
int cmplen = tmplen > len ? len : tmplen;
memset (tmp, 0xa1, tmplen);
- hdf_seek (hfd, offset);
+ hdf_seek (hfd, offset, true);
ReadFile (hfd->handle->h, tmp, tmplen, &outlen2, NULL);
- if (memcmp (hfd->cache, tmp, cmplen) != 0 || outlen != len)
- gui_message (_T("\"%s\"\n\nblock zero write failed! Make sure WinUAE has Windows Administrator privileges."), name);
+ if (memcmp (hfd->cache, tmp, cmplen) != 0 || outlen != len) {
+ gui_message (_T("\"%s\"\n\nblock zero write failed! Make sure WinUAE has Windows Administrator privileges. Error=%d"), name, err);
+ *error = 45;
+ }
VirtualFree (tmp, 0, MEM_RELEASE);
}
}
return outlen;
}
-int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
+int hdf_write_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int got = 0;
uae_u8 *p = (uae_u8*)buffer;
+ uae_u32 error2 = 0;
+
+ if (error) {
+ *error = 0;
+ } else {
+ error = &error2;
+ }
if (hfd->handle_valid == HDF_HANDLE_WIN32_CHS)
return 0;
while (len > 0) {
int maxlen = len > CACHE_SIZE ? CACHE_SIZE : len;
- int ret = hdf_write_2 (hfd, p, offset, maxlen);
+ int ret = hdf_write_2(hfd, p, offset, maxlen, error);
if (ret < 0)
return ret;
got += ret;
if (nomedia) {
_tcscpy (tmp, _T("N/A"));
} else {
- if (size >= 1024 * 1024 * 1024)
+ if (size == 0)
+ _tcscpy(tmp, _T("?"));
+ else if (size >= 1024 * 1024 * 1024)
_stprintf (tmp, _T("%.1fG"), ((double)(uae_u32)(size / (1024 * 1024))) / 1024.0);
else if (size < 10 * 1024 * 1024)
_stprintf (tmp, _T("%lldK"), size / 1024);