From cc0137e72b7a7cadb152fb376c3ac50b369044ef Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 6 Sep 2023 20:17:52 +0300 Subject: [PATCH] Add harddrive 0x76 partition support updates and fixes. --- filesys.cpp | 32 +++--- gayle.cpp | 8 +- hardfile.cpp | 195 +++++++++++++++++++++++------------- ide.cpp | 15 ++- include/filesys.h | 10 +- od-win32/hardfile_win32.cpp | 127 ++++++++++++++++------- od-win32/win32gui.cpp | 12 ++- 7 files changed, 265 insertions(+), 134 deletions(-) diff --git a/filesys.cpp b/filesys.cpp index ac693ebd..460a039a 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -8258,6 +8258,7 @@ static void dump_partinfo (struct hardfiledata *hfd, uae_u8 *pp) uae_u32 block, flags; uae_u8 buf[512]; TCHAR dt[32]; + uae_u32 error = 0; flags = rl (pp + 20); pp[37 + pp[36]] = 0; @@ -8286,7 +8287,7 @@ static void dump_partinfo (struct hardfiledata *hfd, uae_u8 *pp) 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); @@ -8319,6 +8320,7 @@ static void dumprdbblock(const uae_u8 *buf, int 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)); @@ -8339,7 +8341,7 @@ static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, u 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); @@ -8362,7 +8364,7 @@ static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, u 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); @@ -8412,6 +8414,7 @@ static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no, 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; @@ -8426,7 +8429,7 @@ static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no, 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; } @@ -8503,6 +8506,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip 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; @@ -8558,7 +8562,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip 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); @@ -8636,7 +8640,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip 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); @@ -8671,7 +8675,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip 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); @@ -8705,6 +8709,7 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum, 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) { @@ -8729,8 +8734,8 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum, } 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) @@ -8741,13 +8746,14 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum, 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); } } @@ -8813,6 +8819,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s 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) { @@ -8829,7 +8836,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s 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; @@ -8956,6 +8963,7 @@ static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx) int unit_no = no & 65535; int sub_no = no >> 16; int type; + uae_u32 error = 0; if (unit_no >= MAX_FILESYSTEM_UNITS) return -2; @@ -9085,7 +9093,7 @@ static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx) 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); diff --git a/gayle.cpp b/gayle.cpp index e2f39385..4db68d1a 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -1425,8 +1425,9 @@ static void check_sram_flush (int addr) int start = pcmcia_write_min & mask; int end = (pcmcia_write_max + blocksize - 1) & mask; int len = end - start; + uae_u32 error = 0; if (len > 0) { - hdf_write (&pcmcia_disk->hfd, pcmcia_common + start, start, len); + hdf_write (&pcmcia_disk->hfd, pcmcia_common + start, start, len, &error); pcmcia_write_min = -1; pcmcia_write_max = -1; } @@ -1511,6 +1512,7 @@ static int initpcmcia (const TCHAR *path, int readonly, int type, int reset, str if (!pcmcia_disk->hfd.drive_empty) { int extrasize = 0; + uae_u32 error = 0; pcmcia_common_size = (int)pcmcia_disk->hfd.virtsize; if (pcmcia_disk->hfd.virtsize > 4 * 1024 * 1024) { write_log (_T("PCMCIA SRAM: too large device, %llu bytes\n"), pcmcia_disk->hfd.virtsize); @@ -1521,10 +1523,10 @@ static int initpcmcia (const TCHAR *path, int readonly, int type, int reset, str pcmcia_common_size = 4 * 1024 * 1024; } pcmcia_common = xcalloc (uae_u8, pcmcia_common_size); - hdf_read (&pcmcia_disk->hfd, pcmcia_common, 0, pcmcia_common_size); + hdf_read (&pcmcia_disk->hfd, pcmcia_common, 0, pcmcia_common_size, &error); pcmcia_card = 1; if (extrasize >= 512 && extrasize < 1 * 1024 * 1024) { - hdf_read(&pcmcia_disk->hfd, pcmcia_attrs, pcmcia_common_size, extrasize); + hdf_read(&pcmcia_disk->hfd, pcmcia_attrs, pcmcia_common_size, extrasize, &error); write_log(_T("PCMCIA SRAM: Attribute data read %ld bytes\n"), extrasize); pcmcia_attrs_full = 1; } else { diff --git a/hardfile.cpp b/hardfile.cpp index 55484999..9f2165d8 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -239,6 +239,7 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int uae_u8 block[512]; int i; uae_u64 minsize = 512 * 1024 * 1024; + uae_u32 error = 0; if (size <= minsize) { *phead = 1; @@ -246,8 +247,8 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int } 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; @@ -255,7 +256,7 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int 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 && @@ -561,6 +562,8 @@ void hdf_hd_close (struct hd_hardfiledata *hfd) 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; @@ -580,8 +583,8 @@ int hdf_hd_open (struct hd_hardfiledata *hfd) 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); @@ -608,24 +611,24 @@ static uae_u32 vhd_checksum (uae_u8 *p, int offset) 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) @@ -634,6 +637,7 @@ 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; @@ -694,7 +698,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname) 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) @@ -710,7 +714,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname) 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; @@ -722,7 +726,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname) 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) @@ -735,7 +739,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname) 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; @@ -802,6 +806,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_ { 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; @@ -826,7 +831,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_ 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; } @@ -837,7 +842,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_ // 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; } @@ -857,7 +862,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset) { uae_u8 *buf, *p; int len; - uae_u32 block; + uae_u32 block, error = 0; int v; len = hfd->vhd_blocksize + hfd->vhd_bitmapsize + 512; @@ -869,7 +874,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset) } // 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")); @@ -883,7 +888,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset) 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; } @@ -895,6 +900,7 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae { 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; @@ -918,14 +924,14 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae 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; } @@ -933,7 +939,7 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae 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; } @@ -1083,9 +1089,10 @@ end: 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) { @@ -1106,7 +1113,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in 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; @@ -1133,7 +1140,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in } #endif else - ret = hdf_read_target (hfd, buffer, offset, len); + ret = hdf_read_target (hfd, buffer, offset, len, error); if (ret <= 0) return ret; @@ -1141,7 +1148,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in 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; @@ -1162,9 +1169,9 @@ static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i 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; @@ -1189,7 +1196,7 @@ static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i } #endif else - ret = hdf_write_target (hfd, buffer, offset, len); + ret = hdf_write_target(hfd, buffer, offset, len, error); if (ret <= 0) return ret; @@ -1234,10 +1241,10 @@ static void hdf_byteswap (void *v, int len) } } -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; @@ -1251,61 +1258,76 @@ int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int le 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; @@ -1315,7 +1337,7 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data 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; @@ -1323,7 +1345,7 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data 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; @@ -1333,16 +1355,16 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data } 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; @@ -1352,7 +1374,7 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat 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; @@ -1361,7 +1383,7 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat 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; @@ -1493,6 +1515,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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]; @@ -1749,7 +1772,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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; @@ -1785,7 +1812,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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) @@ -2047,7 +2078,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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)) @@ -2062,7 +2097,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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) */ { @@ -2080,7 +2119,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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; @@ -2110,7 +2153,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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)) @@ -2125,7 +2172,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua 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)) @@ -2634,7 +2685,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc 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 @@ -2665,7 +2716,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc 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 @@ -2695,7 +2746,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc 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; @@ -2732,7 +2783,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc 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 diff --git a/ide.cpp b/ide.cpp index 8c1a5210..f770efed 100644 --- a/ide.cpp +++ b/ide.cpp @@ -976,6 +976,7 @@ static void do_process_rw_command (struct ide_hdf *ide) unsigned int cyl, head, sec, nsec, nsec_total; uae_u64 lba; bool last = true; + uae_u32 error = 0; ide->data_offset = 0; @@ -1016,9 +1017,14 @@ static void do_process_rw_command (struct ide_hdf *ide) write_log (_T("IDE%d write, %d/%d bytes, buffer offset %d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset); } else { if (ide->buffer_offset == 0) { - hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize); + hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize, &error); if (IDE_LOG > 1) write_log(_T("IDE%d initial read, %d bytes\n"), ide->num, nsec_total * ide->blocksize); + if (error) { + ide_data_ready(ide); + ide_fail_err(ide, IDE_ERR_IDNF); + return; + } } if (IDE_LOG > 1) write_log (_T("IDE%d read, read %d/%d bytes, buffer offset=%d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset); @@ -1033,7 +1039,12 @@ static void do_process_rw_command (struct ide_hdf *ide) if (IDE_LOG > 1) write_log(_T("IDE%d write finished, %d bytes\n"), ide->num, ide->start_nsec * ide->blocksize); ide->intdrq = false; - hdf_write (&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize); + hdf_write(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize, &error); + if (error) { + ide_data_ready(ide); + ide_fail_err(ide, IDE_ERR_IDNF); + return; + } } end: diff --git a/include/filesys.h b/include/filesys.h index 0e52580c..f8538e80 100644 --- a/include/filesys.h +++ b/include/filesys.h @@ -132,9 +132,9 @@ extern int hdf_open (struct hardfiledata *hfd); extern int hdf_open (struct hardfiledata *hfd, const TCHAR *altname); extern int hdf_dup (struct hardfiledata *dhfd, const struct hardfiledata *shfd); extern void hdf_close (struct hardfiledata *hfd); -extern int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len); -extern int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len); -extern int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len); +extern int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error); +extern int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error); +extern int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error); extern int hdf_getnumharddrives (void); extern TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangerousdrive, uae_u32 *outflags); extern int get_native_path(TrapContext *ctx, uae_u32 lock, TCHAR *out); @@ -152,8 +152,8 @@ extern int hdf_init_target (void); extern int hdf_open_target (struct hardfiledata *hfd, const TCHAR *name); extern int hdf_dup_target (struct hardfiledata *dhfd, const struct hardfiledata *shfd); extern void hdf_close_target (struct hardfiledata *hfd); -extern int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len); -extern int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len); +extern int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error); +extern int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error); extern int hdf_resize_target (struct hardfiledata *hfd, uae_u64 newsize); extern void getchsgeometry (uae_u64 size, int *pcyl, int *phead, int *psectorspertrack); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 70f6fa38..0a94128b 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -1720,10 +1720,11 @@ static bool getdeviceinfo (HANDLE hDevice, struct uae_driveinfo *udi) _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 != '_') { @@ -1853,6 +1854,8 @@ static void lock_drive(struct hardfiledata *hfd, const TCHAR *name, HANDLE drvha 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)) { @@ -1972,15 +1975,20 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) 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) { @@ -2024,8 +2032,8 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) 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) { @@ -2273,7 +2281,7 @@ int hdf_dup_target (struct hardfiledata *dhfd, const struct hardfiledata *shfd) 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; @@ -2285,14 +2293,23 @@ static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset) 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) { @@ -2394,7 +2411,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int 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); @@ -2409,7 +2426,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int 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) @@ -2435,7 +2452,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int 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); @@ -2462,13 +2479,17 @@ int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) #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); @@ -2477,8 +2498,10 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i 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); @@ -2486,8 +2509,10 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i 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) { @@ -2496,16 +2521,26 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i } 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; @@ -2523,7 +2558,7 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int 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); @@ -2536,7 +2571,7 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int 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) @@ -2548,20 +2583,26 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int 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) { @@ -2572,12 +2613,17 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, 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; @@ -2585,10 +2631,12 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, 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); } } @@ -2598,10 +2646,17 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, 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; @@ -2610,7 +2665,7 @@ int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in 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; @@ -3411,7 +3466,9 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero 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); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 2c9e5ea2..f3e3610d 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -14395,6 +14395,7 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf) uae_u8 id[512]; int i; struct hardfiledata hfd; + uae_u32 error = 0; memset (id, 0, sizeof id); memset (&hfd, 0, sizeof hfd); @@ -14403,15 +14404,15 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf) hdf->rdb = 0; if (hdf_open (&hfd, current_hfdlg.ci.rootdir) > 0) { for (i = 0; i < 16; i++) { - hdf_read_rdb (&hfd, id, i * 512, 512); - if (i == 0 && !memcmp (id + 2, "CIS", 3)) { + hdf_read_rdb (&hfd, id, i * 512, 512, &error); + if (!error && i == 0 && !memcmp (id + 2, "CIS", 3)) { hdf->ci.controller_type = HD_CONTROLLER_TYPE_CUSTOM_FIRST; hdf->ci.controller_type_unit = 0; break; } bool babe = id[0] == 0xBA && id[1] == 0xBE; // A2090 - if (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) || - (id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0) || babe) { + if (!error && (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) || + (id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0) || babe)) { // RDSK or ADIDE "encoded" RDSK int blocksize = 512; if (!babe) @@ -14959,6 +14960,7 @@ static void updatehdfinfo(HWND hDlg, bool force, bool defaults, bool realdrive) TCHAR tmp[200], tmp2[200]; TCHAR idtmp[17]; bool phys = is_hdf_rdb(); + uae_u32 error = 0; bsize = 0; if (force) { @@ -14975,7 +14977,7 @@ static void updatehdfinfo(HWND hDlg, bool force, bool defaults, bool realdrive) if (hdf_open (&hfd, current_hfdlg.ci.rootdir) > 0) { open = true; for (i = 0; i < 16; i++) { - hdf_read (&hfd, id, i * 512, 512); + hdf_read (&hfd, id, i * 512, 512, &error); bsize = hfd.virtsize; current_hfdlg.size = hfd.virtsize; if (!memcmp (id, "RDSK", 4) || !memcmp (id, "CDSK", 4)) { -- 2.47.3