]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Filesystem invalid filename check update, A2090 partition table support.
authorToni Wilen <twilen@winuae.net>
Tue, 4 Jul 2017 09:21:04 +0000 (12:21 +0300)
committerToni Wilen <twilen@winuae.net>
Tue, 4 Jul 2017 09:21:04 +0000 (12:21 +0300)
filesys.cpp
include/fsdb.h
od-win32/fsdb_win32.cpp

index 2083f62be1837f03fce11608880b8262e1e03448..4e53678751121d4a0b98f12d3973406652db7769 100644 (file)
@@ -177,8 +177,6 @@ typedef struct {
        bool unknown_media; /* ID_UNREADABLE_DISK */
        int bootpri; /* boot priority. -128 = no autoboot, -129 = no mount */
        int devno;
-       int controller_type;
-       int controller_unit;
        bool wasisempty; /* if true, this unit was created empty */
        bool canremove; /* if true, this unit can be safely ejected and remounted */
        bool configureddrive; /* if true, this is drive that was manually configured */
@@ -221,8 +219,8 @@ static struct uaedev_mount_info mountinfo;
 
 int nr_units (void)
 {
-       int i, cnt = 0;
-       for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
+       int cnt = 0;
+       for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
                if (mountinfo.ui[i].open > 0)
                        cnt++;
        }
@@ -231,15 +229,15 @@ int nr_units (void)
 
 int nr_directory_units (struct uae_prefs *p)
 {
-       int i, cnt = 0;
+       int cnt = 0;
        if (p) {
-               for (i = 0; i < p->mountitems; i++) {
+               for (int i = 0; i < p->mountitems; i++) {
                        if (p->mountconfig[i].ci.controller_type == HD_CONTROLLER_TYPE_UAE)
                                cnt++;
                }
        } else {
-               for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
-                       if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller_type == HD_CONTROLLER_TYPE_UAE)
+               for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
+                       if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].hf.ci.controller_type == HD_CONTROLLER_TYPE_UAE)
                                cnt++;
                }
        }
@@ -381,7 +379,7 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo *
 #endif
                }
        } else if (uci->ci.type != UAEDEV_TAPE) {
-               if (ui->controller_type == HD_CONTROLLER_TYPE_UAE) { // what is this? || (ui->controller && p->cs_ide)) {
+               if (ui->hf.ci.controller_type == HD_CONTROLLER_TYPE_UAE) { // what is this? || (ui->controller && p->cs_ide)) {
                        mi->ismounted = 1;
                        if (uci->ci.type == UAEDEV_HDF)
                                mi->ismedia = ui->hf.drive_empty ? false : true;
@@ -442,10 +440,9 @@ static void stripsemicolon (TCHAR *s)
 }
 static void stripspace (TCHAR *s)
 {
-       int i;
        if (!s)
                return;
-       for (i = 0; i < _tcslen (s); i++) {
+       for (int i = 0; i < _tcslen (s); i++) {
                if (s[i] == ' ')
                        s[i] = '_';
        }
@@ -637,9 +634,31 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                        return -1;
                }
        }
+       for (;;) {
+               bool retry = false;
+               for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
+                       int hf = is_hardfile(i);
+                       if (nr == i || !mountinfo.ui[i].open || mountinfo.ui[i].rootdir == NULL)
+                               continue;
+                       if (hf != FILESYS_HARDDRIVE && hf != FILESYS_HARDFILE && hf != FILESYS_HARDFILE_RDB)
+                               continue;
+                       if (mountinfo.ui[i].hf.ci.controller_unit == c.controller_unit) {
+                               c.controller_unit++;
+                               if (c.controller_unit >= MAX_FILESYSTEM_UNITS) {
+                                       error_log (_T("directory/hardfile '%s' invalid unit number."), c.rootdir);
+                                       return -1;
+                               }
+                               retry = true;
+                       }
+               }
+               if (!retry)
+                       break;
+       }
+
 
        ui = &mountinfo.ui[nr];
        memset (ui, 0, sizeof (UnitInfo));
+       memcpy(&ui->hf.ci, &c, sizeof c);
 
        if (iscd) {
                ui->unit_type = UNIT_CDFS;
@@ -657,7 +676,6 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                ui->volflags = flags;
        } else {
                ui->unit_type = UNIT_FILESYSTEM;
-               memcpy (&ui->hf.ci, &c, sizeof (struct uaedev_config_info));
                ui->hf.unitnum = nr;
                ui->volname = 0;
                if (ui->hf.ci.rootdir[0]) {
@@ -2526,7 +2544,7 @@ static TCHAR *get_nname (Unit *unit, a_inode *base, TCHAR *rel, TCHAR **modified
                return 0;
        /* A file called "." (or whatever else is invalid on this filesystem)
        * does not exist, as far as the Amiga side is concerned.  */
-       if (fsdb_name_invalid_dir (rel))
+       if (fsdb_name_invalid_dir (base, rel))
                return 0;
 
        /* See if we have a file that has the same name as the aname we are
@@ -2550,7 +2568,7 @@ static TCHAR *create_nname (Unit *unit, a_inode *base, TCHAR *rel)
 
        /* If the name is used otherwise in the directory (or globally), we
        * need a new unique nname.  */
-       if (fsdb_name_invalid (rel) || fsdb_used_as_nname (base, rel)) {
+       if (fsdb_name_invalid (base, rel) || fsdb_used_as_nname (base, rel)) {
 #if 0
 oh_dear:
 #endif
@@ -4452,7 +4470,7 @@ static int action_examine_all_do(TrapContext *ctx, Unit *unit, uaecptr lock, ExA
                if (!eak->fn) {
                        do {
                                ok = filesys_readdir(d, fn, &uniq);
-                       } while (ok && d->fstype == FS_DIRECTORY && (filesys_name_invalid (fn) || fsdb_name_invalid_dir (fn)));
+                       } while (ok && d->fstype == FS_DIRECTORY && (filesys_name_invalid (fn) || fsdb_name_invalid_dir (NULL, fn)));
                        if (!ok)
                                return 0;
                } else {
@@ -4782,7 +4800,7 @@ static void populate_directory (Unit *unit, a_inode *base)
                like "..", "." etc.  */
                do {
                        ok = filesys_readdir(d, fn, &uniq);
-               } while (ok && d->fstype == FS_DIRECTORY && (filesys_name_invalid (fn) || fsdb_name_invalid_dir (fn)));
+               } while (ok && d->fstype == FS_DIRECTORY && (filesys_name_invalid (fn) || fsdb_name_invalid_dir (NULL, fn)));
                if (!ok)
                        break;
                /* This calls init_child_aino, which will notice that the parent is
@@ -7776,6 +7794,10 @@ static uae_u32 rl (uae_u8 *p)
 {
        return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
 }
+static uae_u16 rw (uae_u8 *p)
+{
+       return (p[0] << 8) | (p[1]);
+}
 
 static int rdb_checksum (const uae_char *id, uae_u8 *p, int block)
 {
@@ -7989,15 +8011,117 @@ static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, u
        }
 }
 
-#define rdbmnt write_log (_T("Mounting uaehf.device %d (%d) (size=%llu):\n"), unit_no, partnum, hfd->virtsize);
+static void get_new_device (TrapContext *ctx, int type, uaecptr parmpacket, TCHAR **devname, uaecptr *devname_amiga, int unit_no)
+{
+       TCHAR buffer[80];
+       uaecptr expbase = trap_get_long(ctx, parmpacket + PP_EXPLIB);
 
-static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacket)
+       if (*devname == 0 || _tcslen (*devname) == 0) {
+               int un = unit_no;
+               for (;;) {
+                       _stprintf (buffer, type == FILESYS_CD ? _T("CD%d") : _T("DH%d"), un++);
+                       if (type == FILESYS_CD)
+                               *devname = my_strdup (buffer);
+                       if (!device_isdup(ctx, expbase, buffer))
+                               break;
+               }
+       } else {
+               _tcscpy (buffer, *devname);
+       }
+       *devname_amiga = ds (device_dupfix(ctx, expbase, buffer));
+       if (type == FILESYS_CD)
+               write_log (_T("FS: mounted CD unit %s\n"), buffer);
+       else if (type == FILESYS_VIRTUAL)
+               write_log (_T("FS: mounted virtual unit %s (%s)\n"), buffer, mountinfo.ui[unit_no].rootdir);
+       else
+               write_log (_T("FS: mounted HDF unit %s (%04x-%08x, %s)\n"), buffer,
+               (uae_u32)(mountinfo.ui[unit_no].hf.virtsize >> 32),
+               (uae_u32)(mountinfo.ui[unit_no].hf.virtsize),
+               mountinfo.ui[unit_no].rootdir);
+}
+
+#define rdbmnt write_log (_T("Mounting uaehf.device %d (%d) (size=%llu):\n"), unit_no, partnum, hfd->virtsize)
+
+static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacket)
+{
+       uae_u8 bufrdb2[FILESYS_MAX_BLOCKSIZE] = { 0 };
+       struct hardfiledata *hfd = &uip->hf;
+       struct uaedev_config_info *ci = &uip[unit_no].hf.ci;
+       uae_u32 bad;
+       
+       // blocksize != 128?
+       if (bufrdb[0x20] != 0 || bufrdb[0x21] != 0 || bufrdb[0x22] != 0 || bufrdb[0x23] != 0x80)
+               return 0;
+
+       bad = rl(bufrdb + 4);
+       if (bad) {
+               hdf_read_rdb(hfd, bufrdb2, bad * hfd->ci.blocksize, hfd->ci.blocksize);
+               if (bufrdb2[0] != 0xBA || bufrdb2[1] != 0xD1)
+                       return 0;
+       }
+
+       if (partnum > 0)
+               return -2;
+
+       if (uip->bootpri <= -129) {
+               return -1;
+       }
+
+       if (bad) {
+               uae_u16 badnum = (bufrdb2[2] << 8) | bufrdb2[3];
+               if (badnum) {
+                       write_log(_T("A2090 partition table: bad block table is not empty, bad blocks not yet supported!\n"));
+               }
+       }
+
+       hfd->rdbcylinders = rl(bufrdb + 0x08);
+       hfd->rdbsectors = rw(bufrdb + 0x18);
+       hfd->rdbheads = rw(bufrdb + 0x1a);
+
+       write_log (_T("Mounting uaehf.device:%d %d (%d):\n"), uip->hf.ci.controller_unit, unit_no, partnum);
+       get_new_device(ctx, FILESYS_HARDFILE_RDB, parmpacket, &uip->devname, &uip->rdb_devname_amiga[partnum], unit_no);
+       trap_put_long(ctx, parmpacket, uip->rdb_devname_amiga[partnum]);
+       trap_put_long(ctx, parmpacket + 4, ROM_hardfile_resname);
+       trap_put_long(ctx, parmpacket + 8, uip->devno);
+       trap_put_long(ctx, parmpacket + 12, 0); /* Device flags */
+       for (int i = 0; i < 12 * 4; i++)
+               trap_put_byte(ctx, parmpacket + 16 + i, bufrdb[0x1c + i]);
+
+       uae_u32 dostype = 0x444f5300;
+       if (ci->dostype) // forced dostype?
+               dostype = ci->dostype;
+
+       // A2090 Environment Table Size is only 11
+       int ts = trap_get_long(ctx, parmpacket + 16 + 0 * 4);
+       while (ts < 16) {
+               ts++;
+               if (ts == 12) // BufMem Type
+                       trap_put_long(ctx, parmpacket + 16 + 12 * 4, 1);
+               if (ts == 13) // Max Transfer
+                       trap_put_long(ctx, parmpacket + 16 + 13 * 4, 0x7fffffff);
+               if (ts == 14) // Mask
+                       trap_put_long(ctx, parmpacket + 16 + 14 * 4, 0xfffffffe);
+               if (ts == 15) // BootPri
+                       trap_put_long(ctx, parmpacket + 16 + 15 * 4, uip->bootpri);
+               if (ts == 16) // DosType
+                       trap_put_long(ctx, parmpacket + 16 + 16 * 4, dostype);
+       }
+       trap_put_long(ctx, parmpacket + 16 + 0 * 4, ts);
+
+       uip->rdb_dostype = dostype;
+
+       if (uip->bootpri <= -128) /* not bootable */
+               trap_set_dreg(ctx, 7, trap_get_dreg(ctx, 7) & ~1);
+
+       return 2;
+}
+
+static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacket)
 {
-       int lastblock = 63, blocksize, readblocksize, badblock, driveinitblock;
+       int blocksize, readblocksize, badblock, driveinitblock;
        TCHAR dt[32];
-       uae_u8 bufrdb[FILESYS_MAX_BLOCKSIZE], *buf = 0;
-       uae_u8 *fsmem = 0;
-       int rdblock, partblock, fileblock, lsegblock, i;
+       uae_u8 *fsmem = 0, *buf = 0;
+       int partblock, fileblock, lsegblock;
        uae_u32 flags;
        struct hardfiledata *hfd = &uip->hf;
        uae_u32 dostype;
@@ -8008,46 +8132,6 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
        TCHAR *s;
        bool showdebug = partnum == 0;
 
-       write_log (_T("%s:\n"), uip->rootdir);
-       if (hfd->drive_empty) {
-               rdbmnt
-               write_log (_T("ignored, drive is empty\n"));
-               return -2;
-       }
-       if (hfd->ci.blocksize == 0) {
-               rdbmnt
-               write_log (_T("failed, blocksize == 0\n"));
-               return -1;
-       }
-       if (lastblock * hfd->ci.blocksize > hfd->virtsize) {
-               rdbmnt
-               write_log (_T("failed, too small (%d*%d > %llu)\n"), lastblock, hfd->ci.blocksize, hfd->virtsize);
-               return -2;
-       }
-       for (rdblock = 0; rdblock < lastblock; rdblock++) {
-               hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
-               if (rdb_checksum ("RDSK", bufrdb, rdblock))
-                       break;
-               if (rdb_checksum ("CDSK", bufrdb, rdblock))
-                       break;
-               hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
-               if (!memcmp ("RDSK", bufrdb, 4)) {
-                       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);
-                               break;
-                       }
-               }
-       }
-       if (rdblock == lastblock) {
-               rdbmnt
-               write_log (_T("failed, no RDB detected\n"));
-               return -2;
-       }
        blocksize = rl (bufrdb + 16);
        readblocksize = blocksize > hfd->ci.blocksize ? blocksize : hfd->ci.blocksize;
 
@@ -8092,7 +8176,7 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
                write_log (_T("RDSK dump end\n"));
        }
 
-       for (i = 0; i <= partnum; i++) {
+       for (int i = 0; i <= partnum; i++) {
                if (i == 0)
                        partblock = rl (bufrdb + 28);
                else
@@ -8111,7 +8195,7 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
                }
        }
 
-       rdbmnt
+       rdbmnt;
        flags = rl (buf + 20);
        if ((flags & 2) || uip->bootpri <= -129) { /* do not mount */
                err = -1;
@@ -8130,7 +8214,7 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
        trap_put_long(ctx, parmpacket + 4, ROM_hardfile_resname);
        trap_put_long(ctx, parmpacket + 8, uip->devno);
        trap_put_long(ctx, parmpacket + 12, 0); /* Device flags */
-       for (i = 0; i < PP_MAXSIZE; i++)
+       for (int i = 0; i < (17 + 15) * 4; i++)
                trap_put_byte(ctx, parmpacket + 16 + i, buf[128 + i]);
        dostype = trap_get_long(ctx, parmpacket + 80);
        uip->rdb_dostype = dostype;
@@ -8203,13 +8287,13 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
                goto error;
        }
 
-       for (i = 0; i < 140; i++)
+       for (int i = 0; i < 140; i++)
                trap_put_byte(ctx, parmpacket + PP_FSHDSTART + i, buf[32 + i]);
        trap_put_long(ctx, parmpacket + PP_FSHDSTART, dostype);
        /* we found required FSHD block */
        fsmem = xmalloc (uae_u8, 262144);
        lsegblock = rl (buf + 72);
-       i = 0;
+       int cnt = 0;
        for (;;) {
                int pb = lsegblock;
                if (!legalrdbblock (uip, lsegblock))
@@ -8224,18 +8308,18 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
                lsegblock = rl (buf + 16);
                if (lsegblock == pb)
                        goto error;
-               if ((i + 1) * (blocksize - 20) >= 262144)
+               if ((cnt + 1) * (blocksize - 20) >= 262144)
                        goto error;
-               memcpy (fsmem + i * (blocksize - 20), buf + 20, blocksize - 20);
-               i++;
+               memcpy (fsmem + cnt * (blocksize - 20), buf + 20, blocksize - 20);
+               cnt++;
                if (lsegblock == -1)
                        break;
        }
-       write_log (_T("RDB: Filesystem loaded, %d bytes\n"), i * (blocksize - 20));
-       trap_put_long(ctx, parmpacket + PP_FSSIZE, i * (blocksize - 20)); /* RDB filesystem size hack */
+       write_log (_T("RDB: Filesystem loaded, %d bytes\n"), cnt * (blocksize - 20));
+       trap_put_long(ctx, parmpacket + PP_FSSIZE, cnt * (blocksize - 20)); /* RDB filesystem size hack */
        trap_put_long(ctx, parmpacket + PP_ADDTOFSRES, -1);
        uip->rdb_filesysstore = fsmem;
-       uip->rdb_filesyssize = i * (blocksize - 20);
+       uip->rdb_filesyssize = cnt * (blocksize - 20);
        xfree (buf);
        return 2;
 error:
@@ -8244,13 +8328,66 @@ error:
        return err;
 }
 
+static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacket)
+{
+       struct hardfiledata *hfd = &uip->hf;
+       int lastblock = 63, rdblock;
+       uae_u8 bufrdb[FILESYS_MAX_BLOCKSIZE];
+
+       write_log (_T("%s:\n"), uip->rootdir);
+       if (hfd->drive_empty) {
+               rdbmnt;
+               write_log (_T("ignored, drive is empty\n"));
+               return -2;
+       }
+       if (hfd->ci.blocksize == 0) {
+               rdbmnt;
+               write_log (_T("failed, blocksize == 0\n"));
+               return -1;
+       }
+       if (lastblock * hfd->ci.blocksize > hfd->virtsize) {
+               rdbmnt;
+               write_log (_T("failed, too small (%d*%d > %llu)\n"), lastblock, hfd->ci.blocksize, hfd->virtsize);
+               return -2;
+       }
+
+       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) {
+                               // A2090 "BABE" partition table?
+                               int v = pt_babe(ctx, bufrdb, uip, unit_no, partnum, parmpacket);
+                               if (v)
+                                       return v;
+                               continue;
+               }
+               if (rdb_checksum ("RDSK", bufrdb, rdblock) || rdb_checksum ("CDSK", bufrdb, rdblock)) {
+                       return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
+               }
+               if (!memcmp ("RDSK", bufrdb, 4)) {
+                       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);
+                               return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
+                       }
+               }
+       }
+
+       rdbmnt;
+       write_log (_T("failed, no supported partition tables detected\n"));
+       return -2;
+}
+
+
 static void addfakefilesys (TrapContext *ctx, uaecptr parmpacket, uae_u32 dostype, int ver, int rev, struct uaedev_config_info *ci)
 {
-       int i;
        uae_u32 flags;
 
        flags = 0x180;
-       for (i = 0; i < 140; i++)
+       for (int i = 0; i < 140; i++)
                trap_put_byte(ctx, parmpacket + PP_FSHDSTART + i, 0);
        if (dostype) {
                trap_put_long(ctx, parmpacket + 80, dostype);
@@ -8291,7 +8428,7 @@ static uaecptr getfakefilesysseg (UnitInfo *uip)
 
 static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, struct uaedev_config_info *ci)
 {
-       int i, size;
+       int size;
        TCHAR tmp[MAX_DPATH];
        TCHAR dt[32];
        uae_u8 buf[512];
@@ -8334,7 +8471,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s
                _tcscpy (tmp, uip->filesysdir);
        } else if ((dostype & 0xffffff00) == DISK_TYPE_DOS) {
                _tcscpy (tmp, currprefs.romfile);
-               i = _tcslen (tmp);
+               int i = _tcslen (tmp);
                while (i > 0 && tmp[i - 1] != '/' && tmp[i - 1] != '\\')
                        i--;
                _tcscpy (tmp + i, _T("FastFileSystem"));
@@ -8385,7 +8522,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s
                zfile_fseek (zf, 0, SEEK_SET);
                uip->rdb_filesysstore = xmalloc (uae_u8, size);
                zfile_fread (uip->rdb_filesysstore, size, 1, zf);
-               for (i = 0; i < size - 6; i++) {
+               for (int i = 0; i < size - 6; i++) {
                        uae_u8 *p = uip->rdb_filesysstore + i;
                        if (p[0] == 'V' && p[1] == 'E' && p[2] == 'R' && p[3] == ':' && p[4] == ' ') {
                                uae_u8 *p2;
@@ -8434,35 +8571,6 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s
        write_log (_T("RDB: faked RDB filesystem %08X (%s %d.%d) loaded. ADD2FS=%d\n"), dostype, dostypes (dt, dostype), ver, rev, oldversion < 0 ? 1 : 0);
        return FILESYS_HARDFILE;
 }
-
-static void get_new_device (TrapContext *ctx, int type, uaecptr parmpacket, TCHAR **devname, uaecptr *devname_amiga, int unit_no)
-{
-       TCHAR buffer[80];
-       uaecptr expbase = trap_get_long(ctx, parmpacket + PP_EXPLIB);
-
-       if (*devname == 0 || _tcslen (*devname) == 0) {
-               int un = unit_no;
-               for (;;) {
-                       _stprintf (buffer, type == FILESYS_CD ? _T("CD%d") : _T("DH%d"), un++);
-                       if (type == FILESYS_CD)
-                               *devname = my_strdup (buffer);
-                       if (!device_isdup(ctx, expbase, buffer))
-                               break;
-               }
-       } else {
-               _tcscpy (buffer, *devname);
-       }
-       *devname_amiga = ds (device_dupfix(ctx, expbase, buffer));
-       if (type == FILESYS_CD)
-               write_log (_T("FS: mounted CD unit %s\n"), buffer);
-       else if (type == FILESYS_VIRTUAL)
-               write_log (_T("FS: mounted virtual unit %s (%s)\n"), buffer, mountinfo.ui[unit_no].rootdir);
-       else
-               write_log (_T("FS: mounted HDF unit %s (%04x-%08x, %s)\n"), buffer,
-               (uae_u32)(mountinfo.ui[unit_no].hf.virtsize >> 32),
-               (uae_u32)(mountinfo.ui[unit_no].hf.virtsize),
-               mountinfo.ui[unit_no].rootdir);
-}
        
 /* Fill in per-unit fields of a parampacket */
 static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx)
@@ -8529,14 +8637,14 @@ static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx)
                type = is_hardfile (unit_no);
                if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE) {
                        /* RDB hardfile */
-                       uip[unit_no].devno = unit_no;
+                       uip[unit_no].devno = uip[unit_no].hf.ci.controller_unit;
                        return rdb_mount(ctx, &uip[unit_no], unit_no, sub_no, parmpacket);
                }
                if (sub_no)
                        return -2;
-               write_log (_T("Mounting uaehf.device %d (%d):\n"), unit_no, sub_no);
+               write_log (_T("Mounting uaehf.device:%d %d (%d):\n"), uip->hf.ci.controller_unit, unit_no, sub_no);
                get_new_device(ctx, type, parmpacket, &uip[unit_no].devname, &uip[unit_no].devname_amiga, unit_no);
-               uip[unit_no].devno = unit_no;
+               uip[unit_no].devno = uip[unit_no].hf.ci.controller_unit;
                trap_put_long(ctx, parmpacket, uip[unit_no].devname_amiga);
                trap_put_long(ctx, parmpacket + 8, uip[unit_no].devno);
                trap_put_long(ctx, parmpacket + 12, 0); /* Device flags */
@@ -9023,13 +9131,12 @@ static a_inode *restore_filesys_get_base (Unit *u, TCHAR *npath)
 
 static TCHAR *makenativepath (UnitInfo *ui, TCHAR *apath)
 {
-       int i;
        TCHAR *pn;
        /* create native path. FIXME: handle 'illegal' characters */
        pn = xcalloc (TCHAR, _tcslen (apath) + 1 + _tcslen (ui->rootdir) + 1);
        _stprintf (pn, _T("%s/%s"), ui->rootdir, apath);
        if (FSDB_DIR_SEPARATOR != '/') {
-               for (i = 0; i < _tcslen (pn); i++) {
+               for (int i = 0; i < _tcslen (pn); i++) {
                        if (pn[i] == '/')
                                pn[i] = FSDB_DIR_SEPARATOR;
                }
index c835a5156569adc0c229254fbd04adcf43f37ab9..9ab37d6ec87f842bde2eb47f8bfdae5784d59e26 100644 (file)
@@ -135,8 +135,8 @@ extern int fsdb_exists (const TCHAR *nname);
 extern int same_aname (const TCHAR *an1, const TCHAR *an2);
 
 /* Filesystem-dependent functions.  */
-extern int fsdb_name_invalid (const TCHAR *n);
-extern int fsdb_name_invalid_dir (const TCHAR *n);
+extern int fsdb_name_invalid (a_inode *, const TCHAR *n);
+extern int fsdb_name_invalid_dir (a_inode *, const TCHAR *n);
 extern int fsdb_fill_file_attrs (a_inode *, a_inode *);
 extern int fsdb_set_file_attrs (a_inode *);
 extern int fsdb_mode_representable_p (const a_inode *, int);
index 0823ff5e86d1c97f2ed6f394d97d75b92ecf51d6..1523c8bfc29035492cd615adbd4b3b9dbf818dc7 100644 (file)
@@ -281,7 +281,7 @@ static a_inode *aino_from_buf (a_inode *base, uae_u8 *buf, int *winmode)
 }
 
 /* Return nonzero for any name we can't create on the native filesystem.  */
-static int fsdb_name_invalid_2 (const TCHAR *n, int dir)
+static int fsdb_name_invalid_2x (const TCHAR *n, int dir)
 {
        int i;
        static char s1[MAX_DPATH];
@@ -310,6 +310,13 @@ static int fsdb_name_invalid_2 (const TCHAR *n, int dir)
        if (c >= 'a' && c <= 'z')
                c -= 32;
 
+       s1[0] = 0;
+       s2[0] = 0;
+       ua_fs_copy (s1, MAX_DPATH, n, -1);
+       au_fs_copy (s2, MAX_DPATH, s1);
+       if (_tcscmp (s2, n) != 0)
+               return 1;
+
        if (currprefs.win32_filesystem_mangle_reserved_names) {
                /* reserved dos devices */
                ll = 0;
@@ -321,7 +328,7 @@ static int fsdb_name_invalid_2 (const TCHAR *n, int dir)
                if (a == 'C' && b == 'O' && c == 'M'  && (d >= '0' && d <= '9')) ll = 4; /* COM# */
                /* AUX.anything, CON.anything etc.. are also illegal names */
                if (ll && (l == ll || (l > ll && n[ll] == '.')))
-                       return 1;
+                       return 3;
 
                /* spaces and periods at the end are a no-no */
                i = l - 1;
@@ -332,31 +339,48 @@ static int fsdb_name_invalid_2 (const TCHAR *n, int dir)
        /* these characters are *never* allowed */
        for (i = 0; i < NUM_EVILCHARS; i++) {
                if (_tcschr (n, evilchars[i]) != 0)
-                       return 1;
+                       return 2;
        }
 
-       s1[0] = 0;
-       s2[0] = 0;
-       ua_fs_copy (s1, MAX_DPATH, n, -1);
-       au_fs_copy (s2, MAX_DPATH, s1);
-       if (_tcscmp (s2, n) != 0)
-               return 1;
-
        return 0; /* the filename passed all checks, now it should be ok */
 }
 
-int fsdb_name_invalid (const TCHAR *n)
+static int fsdb_name_invalid_2 (a_inode *aino, const TCHAR *n, int dir)
+{
+       int v = fsdb_name_invalid_2x(n, dir);
+       if (v <= 1 || !aino)
+               return v;
+       TCHAR *p = build_nname (aino->nname, n);
+       HANDLE h = CreateFile(p, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+       DWORD err = -1;
+       DWORD type = -1;
+       if (h != INVALID_HANDLE_VALUE) {
+               type = GetFileType(h);
+               CloseHandle(h);
+       } else {
+               err = GetLastError();
+       }
+       write_log(_T("H=%08x TYPE=%08x ERR=%08X '%s'\n"), h, type, err, p);
+       xfree(p);
+       if (h != INVALID_HANDLE_VALUE && type != FILE_TYPE_DISK)
+               return 1;
+       if (err == ERROR_INVALID_NAME)
+               return 1;
+       return 0;
+}
+
+int fsdb_name_invalid (a_inode *aino, const TCHAR *n)
 {
-       int v = fsdb_name_invalid_2 (n, 0);
+       int v = fsdb_name_invalid_2 (aino, n, 0);
        if (v <= 0)
                return v;
        write_log (_T("FILESYS: '%s' illegal filename\n"), n);
        return v;
 }
 
-int fsdb_name_invalid_dir (const TCHAR *n)
+int fsdb_name_invalid_dir (a_inode *aino, const TCHAR *n)
 {
-       int v = fsdb_name_invalid_2 (n, 1);
+       int v = fsdb_name_invalid_2 (aino, n, 1);
        if (v <= 0)
                return v;
        write_log (_T("FILESYS: '%s' illegal filename\n"), n);