]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Add harddrive 0x76 partition support updates and fixes.
authorToni Wilen <twilen@winuae.net>
Wed, 6 Sep 2023 17:17:52 +0000 (20:17 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 6 Sep 2023 17:17:52 +0000 (20:17 +0300)
filesys.cpp
gayle.cpp
hardfile.cpp
ide.cpp
include/filesys.h
od-win32/hardfile_win32.cpp
od-win32/win32gui.cpp

index ac693ebdf8b06b7d20bb9e7d9ce37f5bcf0a69a1..460a039a63614022c99b2aa68d727931e7d0e5a5 100644 (file)
@@ -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);
index e2f393855a90de2c86ea042ff3b02be81adf3c3d..4db68d1a945a492c15cdfa375dc626000c36aa3d 100644 (file)
--- 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 {
index 554849992517f73181d82c5e91d53ea158df22c7..9f2165d85c9caa21e72c452fda623f48b6c547d3 100644 (file)
@@ -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 8c1a52100c5e64778b93a6d82591a78491138756..f770efedf43d44e713da9decc2929649c57d3e40 100644 (file)
--- 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:
index 0e52580c0da64e782264efa5f10af7b295efdb30..f8538e805dca0421ca99cb176468b1b47ce23e18 100644 (file)
@@ -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);
index 70f6fa38b0cc8f6b5d704436991d8d4a682f2afe..0a94128b6af463e52d4303117e7a6506ff1abd4e 100644 (file)
@@ -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);
index 2c9e5ea22eb1109be665288055b340c6461c3523..f3e3610de82dc4a1745805e1e9255ecb7b53abec 100644 (file)
@@ -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)) {