From 158d72d7fe6e81b23201e87104f36eba686da148 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 4 Jul 2017 12:21:04 +0300 Subject: [PATCH] Filesystem invalid filename check update, A2090 partition table support. --- filesys.cpp | 331 ++++++++++++++++++++++++++-------------- include/fsdb.h | 4 +- od-win32/fsdb_win32.cpp | 52 +++++-- 3 files changed, 259 insertions(+), 128 deletions(-) diff --git a/filesys.cpp b/filesys.cpp index 2083f62b..4e536787 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -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; } diff --git a/include/fsdb.h b/include/fsdb.h index c835a515..9ab37d6e 100644 --- a/include/fsdb.h +++ b/include/fsdb.h @@ -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); diff --git a/od-win32/fsdb_win32.cpp b/od-win32/fsdb_win32.cpp index 0823ff5e..1523c8bf 100644 --- a/od-win32/fsdb_win32.cpp +++ b/od-win32/fsdb_win32.cpp @@ -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); -- 2.47.3