From a8467dd6fdb69af314c32a1d37d9cd20a7888f27 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 31 May 2020 19:47:29 +0300 Subject: [PATCH] Fix zfile stale/double freed file handle. --- filesys.cpp | 753 +++++++++++++++++++++++---------------------- include/zarchive.h | 1 + zfile.cpp | 10 +- 3 files changed, 386 insertions(+), 378 deletions(-) diff --git a/filesys.cpp b/filesys.cpp index 6e94e06d..570e13d2 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -172,7 +172,6 @@ typedef struct { TCHAR *volname; /* volume name, e.g. CDROM, WORK, etc. */ int volflags; /* volume flags, readonly, stream uaefsdb support */ TCHAR *rootdir; /* root native directory/hdf. empty drive if invalid path */ - struct zvolume *zarchive; TCHAR *rootdirdiff; /* "diff" file/directory */ bool readonly; /* disallow write access? */ bool locked; /* action write protect */ @@ -185,6 +184,7 @@ typedef struct { bool inject_icons; /* inject icons if directory filesystem */ struct hardfiledata hf; + struct zvolume *zarchive; /* Threading stuff */ smp_comm_pipe *volatile unit_pipe, *volatile back_pipe; @@ -219,128 +219,390 @@ struct uaedev_mount_info { static struct uaedev_mount_info mountinfo; -int nr_units (void) -{ - int cnt = 0; - for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) { - if (mountinfo.ui[i].open > 0) - cnt++; - } - return cnt; -} -int nr_directory_units (struct uae_prefs *p) -{ - int cnt = 0; - if (p) { - for (int i = 0; i < p->mountitems; i++) { - if (p->mountconfig[i].ci.controller_type == HD_CONTROLLER_TYPE_UAE) - cnt++; - } - } else { - 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++; - } - } - return cnt; -} +/* minimal AmigaDOS definitions */ -static int is_virtual (int unit_no) -{ - int t = is_hardfile (unit_no); - return t == FILESYS_VIRTUAL || t == FILESYS_CD; -} +/* field offsets in DosPacket */ +#define dp_Type 8 +#define dp_Res1 12 +#define dp_Res2 16 +#define dp_Arg1 20 +#define dp_Arg2 24 +#define dp_Arg3 28 +#define dp_Arg4 32 +#define dp_Arg5 36 -int is_hardfile (int unit_no) -{ - if (mountinfo.ui[unit_no].volname || mountinfo.ui[unit_no].wasisempty || mountinfo.ui[unit_no].unknown_media) { - if (unit_no >= cd_unit_offset && unit_no < cd_unit_offset + cd_unit_number) - return FILESYS_CD; - return FILESYS_VIRTUAL; - } - if (mountinfo.ui[unit_no].hf.ci.sectors == 0) { - if (mountinfo.ui[unit_no].hf.flags & 1) - return FILESYS_HARDDRIVE; - return FILESYS_HARDFILE_RDB; - } - return FILESYS_HARDFILE; -} +#define DP64_INIT -3L -static void close_filesys_unit (UnitInfo *uip) -{ - if (!uip->open) - return; - if (uip->hf.handle_valid) - hdf_close (&uip->hf); - if (uip->volname != 0) - xfree (uip->volname); - if (uip->devname != 0) - xfree (uip->devname); - if (uip->rootdir != 0) - xfree (uip->rootdir); - if (uip->unit_pipe) - xfree (uip->unit_pipe); - if (uip->back_pipe) - xfree (uip->back_pipe); - if (uip->cd_open) { - sys_command_close (uip->cddevno); - isofs_unmount (uip->cdfs_superblock); - } +#define dp64_Type 8 +#define dp64_Res0 12 +#define dp64_Res2 16 +#define dp64_Res1 24 +#define dp64_Arg1 32 +#define dp64_Arg2 40 +#define dp64_Arg3 48 +#define dp64_Arg4 52 +#define dp64_Arg5 56 - uip->unit_pipe = 0; - uip->back_pipe = 0; +#define dp_Max 60 - uip->hf.handle_valid = 0; - uip->volname = 0; - uip->devname = 0; - uip->rootdir = 0; - uip->open = 0; - uip->cd_open = 0; -} +/* result codes */ +#define DOS_TRUE ((uae_u32)-1L) +#define DOS_FALSE (0L) -static uaedev_config_data *getuci (struct uaedev_config_data *uci, int nr) -{ - return &uci[nr]; -} +/* DirEntryTypes */ +#define ST_PIPEFILE -5 +#define ST_LINKFILE -4 +#define ST_FILE -3 +#define ST_ROOT 1 +#define ST_USERDIR 2 +#define ST_SOFTLINK 3 +#define ST_LINKDIR 4 +#if 1 +#define MAXFILESIZE32 (0xffffffff) +#else +/* technically correct but most native + * filesystems don't enforce it + */ +#define MAXFILESIZE32 (0x7fffffff) +#endif +#define MAXFILESIZE32_2G (0x7fffffff) -static UnitInfo *getuip (struct uae_prefs *p, int index) -{ - if (index < 0) - return NULL; - index = p->mountconfig[index].configoffset; - if (index < 0) - return NULL; - return &mountinfo.ui[index]; -} -static int getuindex (struct uae_prefs *p, int index) -{ - if (index < 0) - return -1; - return p->mountconfig[index].unitnum; -} + /* Passed as type to Lock() */ +#define SHARED_LOCK -2 /* File is readable by others */ +#define ACCESS_READ -2 /* Synonym */ +#define EXCLUSIVE_LOCK -1 /* No other access allowed */ +#define ACCESS_WRITE -1 /* Synonym */ -int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo *mi) +/* packet types */ +#define ACTION_CURRENT_VOLUME 7 +#define ACTION_LOCATE_OBJECT 8 +#define ACTION_RENAME_DISK 9 +#define ACTION_FREE_LOCK 15 +#define ACTION_DELETE_OBJECT 16 +#define ACTION_RENAME_OBJECT 17 +#define ACTION_MORE_CACHE 18 +#define ACTION_COPY_DIR 19 +#define ACTION_SET_PROTECT 21 +#define ACTION_CREATE_DIR 22 +#define ACTION_EXAMINE_OBJECT 23 +#define ACTION_EXAMINE_NEXT 24 +#define ACTION_DISK_INFO 25 +#define ACTION_INFO 26 +#define ACTION_FLUSH 27 +#define ACTION_SET_COMMENT 28 +#define ACTION_PARENT 29 +#define ACTION_SET_DATE 34 +#define ACTION_FIND_WRITE 1004 +#define ACTION_FIND_INPUT 1005 +#define ACTION_FIND_OUTPUT 1006 +#define ACTION_END 1007 +#define ACTION_SEEK 1008 +#define ACTION_WRITE_PROTECT 1023 +#define ACTION_IS_FILESYSTEM 1027 +#define ACTION_READ 'R' +#define ACTION_WRITE 'W' + +/* 2.0+ packet types */ +#define ACTION_INHIBIT 31 +#define ACTION_SET_FILE_SIZE 1022 +#define ACTION_LOCK_RECORD 2008 +#define ACTION_FREE_RECORD 2009 +#define ACTION_SAME_LOCK 40 +#define ACTION_CHANGE_MODE 1028 +#define ACTION_FH_FROM_LOCK 1026 +#define ACTION_COPY_DIR_FH 1030 +#define ACTION_PARENT_FH 1031 +#define ACTION_EXAMINE_ALL 1033 +#define ACTION_EXAMINE_FH 1034 +#define ACTION_EXAMINE_ALL_END 1035 + +#define ACTION_FORMAT 1020 +#define ACTION_IS_FILESYSTEM 1027 +#define ACTION_ADD_NOTIFY 4097 +#define ACTION_REMOVE_NOTIFY 4098 + +#define ACTION_READ_LINK 1024 + +/* OS4 64-bit filesize packets */ +#define ACTION_FILESYSTEM_ATTR 3005 +#define ACTION_CHANGE_FILE_POSITION64 8001 +#define ACTION_GET_FILE_POSITION64 8002 +#define ACTION_CHANGE_FILE_SIZE64 8003 +#define ACTION_GET_FILE_SIZE64 8004 + +/* MOS 64-bit filesize packets */ +#define ACTION_SEEK64 26400 +#define ACTION_SET_FILE_SIZE64 26401 +#define ACTION_LOCK_RECORD64 26402 +#define ACTION_FREE_RECORD64 26403 +#define ACTION_QUERY_ATTR 26407 +#define ACTION_EXAMINE_OBJECT64 26408 +#define ACTION_EXAMINE_NEXT64 26409 +#define ACTION_EXAMINE_FH64 26410 + + +/* not supported */ +#define ACTION_MAKE_LINK 1021 + +#define DISK_TYPE_DOS 0x444f5300 /* DOS\0 */ +#define DISK_TYPE_DOS_FFS 0x444f5301 /* DOS\1 */ +#define CDFS_DOSTYPE 0x43440000 /* CDxx */ + +typedef struct _dpacket { + uaecptr packet_addr; + uae_u8 *packet_data; + uae_u8 packet_array[dp_Max]; + bool need_flush; +} dpacket; + +typedef struct { + uae_u32 uniq; + /* The directory we're going through. */ + a_inode *aino; + /* The file we're going to look up next. */ + a_inode *curr_file; +} ExamineKey; + +struct lockrecord { - UnitInfo *ui = getuip (p, index); - struct uaedev_config_data *uci = &p->mountconfig[index]; - UnitInfo uitmp; - TCHAR filepath[MAX_DPATH]; + struct lockrecord *next; + dpacket *packet; + uae_u64 pos; + uae_u64 len; + uae_u32 mode; + uae_u32 timeout; + uae_u32 msg; +}; - memset (mi, 0, sizeof (struct mountedinfo)); - memset (&uitmp, 0, sizeof uitmp); - _tcscpy(mi->rootdir, uci->ci.rootdir); - if (!ui) { - ui = &uitmp; - if (uci->ci.type == UAEDEV_DIR) { - cfgfile_resolve_path_out_load(uci->ci.rootdir, filepath, MAX_DPATH, PATH_DIR); - _tcscpy(mi->rootdir, filepath); - mi->ismounted = 1; - if (filepath[0] == 0) - return FILESYS_VIRTUAL; - if (my_existsfile (filepath)) { - mi->ismedia = 1; +typedef struct key { + struct key *next; + a_inode *aino; + uae_u32 uniq; + struct fs_filehandle *fd; + uae_u64 file_pos; + int dosmode; + int createmode; + int notifyactive; + struct lockrecord *record; +} Key; + +typedef struct notify { + struct notify *next; + uaecptr notifyrequest; + TCHAR *fullname; + TCHAR *partname; +} Notify; + +typedef struct exallkey { + uae_u32 id; + struct fs_dirhandle *dirhandle; + TCHAR *fn; + uaecptr control; +} ExAllKey; + +/* Since ACTION_EXAMINE_NEXT is so braindamaged, we have to keep +* some of these around +*/ + +#define EXKEYS 128 +#define EXALLKEYS 100 +#define MAX_AINO_HASH 128 +#define NOTIFY_HASH_SIZE 127 + +/* handler state info */ + +typedef struct _unit { + struct _unit *next; + + /* Amiga stuff */ + uaecptr dosbase; + /* volume points to our IO board, always 1:1 mapping */ + uaecptr volume; + uaecptr port; /* Our port */ + uaecptr locklist; + + /* Native stuff */ + uae_s32 unit; /* unit number */ + UnitInfo ui; /* unit startup info */ + TCHAR tmpbuf3[256]; + + /* Dummy message processing */ + uaecptr dummy_message; + volatile unsigned int cmds_sent; + volatile unsigned int cmds_complete; + volatile unsigned int cmds_acked; + + /* ExKeys */ + ExamineKey examine_keys[EXKEYS]; + int next_exkey; + unsigned int total_locked_ainos; + + /* ExAll */ + ExAllKey exalls[EXALLKEYS]; + int exallid; + + /* Keys */ + struct key *keys; + + struct lockrecord *waitingrecords; + + a_inode rootnode; + unsigned int aino_cache_size; + a_inode *aino_hash[MAX_AINO_HASH]; + unsigned int nr_cache_hits; + unsigned int nr_cache_lookups; + + struct notify *notifyhash[NOTIFY_HASH_SIZE]; + + int volflags; + uae_u32 lockkey; + bool inhibited; + bool canremovable; + /* increase when media is changed. + * used to detect if cached aino is valid + */ + int mountcount; + int mount_changed; + void *cdfs_superblock; + + TCHAR *mount_volume; + TCHAR *mount_rootdir; + bool mount_readonly; + int mount_flags; + + int reinsertdelay; + TCHAR *newvolume; + TCHAR *newrootdir; + bool newreadonly; + int newflags; + +} Unit; + + +int nr_units (void) +{ + int cnt = 0; + for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) { + if (mountinfo.ui[i].open > 0) + cnt++; + } + return cnt; +} + +int nr_directory_units (struct uae_prefs *p) +{ + int cnt = 0; + if (p) { + for (int i = 0; i < p->mountitems; i++) { + if (p->mountconfig[i].ci.controller_type == HD_CONTROLLER_TYPE_UAE) + cnt++; + } + } else { + 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++; + } + } + return cnt; +} + +static int is_virtual (int unit_no) +{ + int t = is_hardfile (unit_no); + return t == FILESYS_VIRTUAL || t == FILESYS_CD; +} + +int is_hardfile (int unit_no) +{ + if (mountinfo.ui[unit_no].volname || mountinfo.ui[unit_no].wasisempty || mountinfo.ui[unit_no].unknown_media) { + if (unit_no >= cd_unit_offset && unit_no < cd_unit_offset + cd_unit_number) + return FILESYS_CD; + return FILESYS_VIRTUAL; + } + if (mountinfo.ui[unit_no].hf.ci.sectors == 0) { + if (mountinfo.ui[unit_no].hf.flags & 1) + return FILESYS_HARDDRIVE; + return FILESYS_HARDFILE_RDB; + } + return FILESYS_HARDFILE; +} + +static void close_filesys_unit (UnitInfo *uip) +{ + if (!uip->open) + return; + if (uip->hf.handle_valid) + hdf_close (&uip->hf); + if (uip->volname != 0) + xfree (uip->volname); + if (uip->devname != 0) + xfree (uip->devname); + if (uip->rootdir != 0) + xfree (uip->rootdir); + if (uip->unit_pipe) + xfree (uip->unit_pipe); + if (uip->back_pipe) + xfree (uip->back_pipe); + if (uip->cd_open) { + sys_command_close (uip->cddevno); + isofs_unmount (uip->cdfs_superblock); + } + + uip->unit_pipe = 0; + uip->back_pipe = 0; + + uip->hf.handle_valid = 0; + uip->volname = 0; + uip->devname = 0; + uip->rootdir = 0; + uip->open = 0; + uip->cd_open = 0; +} + +static uaedev_config_data *getuci (struct uaedev_config_data *uci, int nr) +{ + return &uci[nr]; +} + + +static UnitInfo *getuip (struct uae_prefs *p, int index) +{ + if (index < 0) + return NULL; + index = p->mountconfig[index].configoffset; + if (index < 0) + return NULL; + return &mountinfo.ui[index]; +} +static int getuindex (struct uae_prefs *p, int index) +{ + if (index < 0) + return -1; + return p->mountconfig[index].unitnum; +} + +int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo *mi) +{ + UnitInfo *ui = getuip (p, index); + struct uaedev_config_data *uci = &p->mountconfig[index]; + UnitInfo uitmp; + TCHAR filepath[MAX_DPATH]; + + memset (mi, 0, sizeof (struct mountedinfo)); + memset (&uitmp, 0, sizeof uitmp); + _tcscpy(mi->rootdir, uci->ci.rootdir); + if (!ui) { + ui = &uitmp; + if (uci->ci.type == UAEDEV_DIR) { + cfgfile_resolve_path_out_load(uci->ci.rootdir, filepath, MAX_DPATH, PATH_DIR); + _tcscpy(mi->rootdir, filepath); + mi->ismounted = 1; + if (filepath[0] == 0) + return FILESYS_VIRTUAL; + if (my_existsfile (filepath)) { + mi->ismedia = 1; return FILESYS_VIRTUAL; } if (my_getvolumeinfo (filepath) < 0) @@ -1180,267 +1442,6 @@ struct hardfiledata *get_hardfile_data (int nr) return &uip[nr].hf; } -/* minimal AmigaDOS definitions */ - -/* field offsets in DosPacket */ -#define dp_Type 8 -#define dp_Res1 12 -#define dp_Res2 16 -#define dp_Arg1 20 -#define dp_Arg2 24 -#define dp_Arg3 28 -#define dp_Arg4 32 -#define dp_Arg5 36 - -#define DP64_INIT -3L - -#define dp64_Type 8 -#define dp64_Res0 12 -#define dp64_Res2 16 -#define dp64_Res1 24 -#define dp64_Arg1 32 -#define dp64_Arg2 40 -#define dp64_Arg3 48 -#define dp64_Arg4 52 -#define dp64_Arg5 56 - -#define dp_Max 60 - -/* result codes */ -#define DOS_TRUE ((uae_u32)-1L) -#define DOS_FALSE (0L) - -/* DirEntryTypes */ -#define ST_PIPEFILE -5 -#define ST_LINKFILE -4 -#define ST_FILE -3 -#define ST_ROOT 1 -#define ST_USERDIR 2 -#define ST_SOFTLINK 3 -#define ST_LINKDIR 4 - -#if 1 -#define MAXFILESIZE32 (0xffffffff) -#else -/* technically correct but most native - * filesystems don't enforce it - */ -#define MAXFILESIZE32 (0x7fffffff) -#endif -#define MAXFILESIZE32_2G (0x7fffffff) - -/* Passed as type to Lock() */ -#define SHARED_LOCK -2 /* File is readable by others */ -#define ACCESS_READ -2 /* Synonym */ -#define EXCLUSIVE_LOCK -1 /* No other access allowed */ -#define ACCESS_WRITE -1 /* Synonym */ - -/* packet types */ -#define ACTION_CURRENT_VOLUME 7 -#define ACTION_LOCATE_OBJECT 8 -#define ACTION_RENAME_DISK 9 -#define ACTION_FREE_LOCK 15 -#define ACTION_DELETE_OBJECT 16 -#define ACTION_RENAME_OBJECT 17 -#define ACTION_MORE_CACHE 18 -#define ACTION_COPY_DIR 19 -#define ACTION_SET_PROTECT 21 -#define ACTION_CREATE_DIR 22 -#define ACTION_EXAMINE_OBJECT 23 -#define ACTION_EXAMINE_NEXT 24 -#define ACTION_DISK_INFO 25 -#define ACTION_INFO 26 -#define ACTION_FLUSH 27 -#define ACTION_SET_COMMENT 28 -#define ACTION_PARENT 29 -#define ACTION_SET_DATE 34 -#define ACTION_FIND_WRITE 1004 -#define ACTION_FIND_INPUT 1005 -#define ACTION_FIND_OUTPUT 1006 -#define ACTION_END 1007 -#define ACTION_SEEK 1008 -#define ACTION_WRITE_PROTECT 1023 -#define ACTION_IS_FILESYSTEM 1027 -#define ACTION_READ 'R' -#define ACTION_WRITE 'W' - -/* 2.0+ packet types */ -#define ACTION_INHIBIT 31 -#define ACTION_SET_FILE_SIZE 1022 -#define ACTION_LOCK_RECORD 2008 -#define ACTION_FREE_RECORD 2009 -#define ACTION_SAME_LOCK 40 -#define ACTION_CHANGE_MODE 1028 -#define ACTION_FH_FROM_LOCK 1026 -#define ACTION_COPY_DIR_FH 1030 -#define ACTION_PARENT_FH 1031 -#define ACTION_EXAMINE_ALL 1033 -#define ACTION_EXAMINE_FH 1034 -#define ACTION_EXAMINE_ALL_END 1035 - -#define ACTION_FORMAT 1020 -#define ACTION_IS_FILESYSTEM 1027 -#define ACTION_ADD_NOTIFY 4097 -#define ACTION_REMOVE_NOTIFY 4098 - -#define ACTION_READ_LINK 1024 - -/* OS4 64-bit filesize packets */ -#define ACTION_FILESYSTEM_ATTR 3005 -#define ACTION_CHANGE_FILE_POSITION64 8001 -#define ACTION_GET_FILE_POSITION64 8002 -#define ACTION_CHANGE_FILE_SIZE64 8003 -#define ACTION_GET_FILE_SIZE64 8004 - -/* MOS 64-bit filesize packets */ -#define ACTION_SEEK64 26400 -#define ACTION_SET_FILE_SIZE64 26401 -#define ACTION_LOCK_RECORD64 26402 -#define ACTION_FREE_RECORD64 26403 -#define ACTION_QUERY_ATTR 26407 -#define ACTION_EXAMINE_OBJECT64 26408 -#define ACTION_EXAMINE_NEXT64 26409 -#define ACTION_EXAMINE_FH64 26410 - - -/* not supported */ -#define ACTION_MAKE_LINK 1021 - -#define DISK_TYPE_DOS 0x444f5300 /* DOS\0 */ -#define DISK_TYPE_DOS_FFS 0x444f5301 /* DOS\1 */ -#define CDFS_DOSTYPE 0x43440000 /* CDxx */ - -typedef struct _dpacket { - uaecptr packet_addr; - uae_u8 *packet_data; - uae_u8 packet_array[dp_Max]; - bool need_flush; -} dpacket; - -typedef struct { - uae_u32 uniq; - /* The directory we're going through. */ - a_inode *aino; - /* The file we're going to look up next. */ - a_inode *curr_file; -} ExamineKey; - -struct lockrecord -{ - struct lockrecord *next; - dpacket *packet; - uae_u64 pos; - uae_u64 len; - uae_u32 mode; - uae_u32 timeout; - uae_u32 msg; -}; - -typedef struct key { - struct key *next; - a_inode *aino; - uae_u32 uniq; - struct fs_filehandle *fd; - uae_u64 file_pos; - int dosmode; - int createmode; - int notifyactive; - struct lockrecord *record; -} Key; - -typedef struct notify { - struct notify *next; - uaecptr notifyrequest; - TCHAR *fullname; - TCHAR *partname; -} Notify; - -typedef struct exallkey { - uae_u32 id; - struct fs_dirhandle *dirhandle; - TCHAR *fn; - uaecptr control; -} ExAllKey; - -/* Since ACTION_EXAMINE_NEXT is so braindamaged, we have to keep -* some of these around -*/ - -#define EXKEYS 128 -#define EXALLKEYS 100 -#define MAX_AINO_HASH 128 -#define NOTIFY_HASH_SIZE 127 - -/* handler state info */ - -typedef struct _unit { - struct _unit *next; - - /* Amiga stuff */ - uaecptr dosbase; - /* volume points to our IO board, always 1:1 mapping */ - uaecptr volume; - uaecptr port; /* Our port */ - uaecptr locklist; - - /* Native stuff */ - uae_s32 unit; /* unit number */ - UnitInfo ui; /* unit startup info */ - TCHAR tmpbuf3[256]; - - /* Dummy message processing */ - uaecptr dummy_message; - volatile unsigned int cmds_sent; - volatile unsigned int cmds_complete; - volatile unsigned int cmds_acked; - - /* ExKeys */ - ExamineKey examine_keys[EXKEYS]; - int next_exkey; - unsigned int total_locked_ainos; - - /* ExAll */ - ExAllKey exalls[EXALLKEYS]; - int exallid; - - /* Keys */ - struct key *keys; - - struct lockrecord *waitingrecords; - - a_inode rootnode; - unsigned int aino_cache_size; - a_inode *aino_hash[MAX_AINO_HASH]; - unsigned int nr_cache_hits; - unsigned int nr_cache_lookups; - - struct notify *notifyhash[NOTIFY_HASH_SIZE]; - - int volflags; - uae_u32 lockkey; - bool inhibited; - bool canremovable; - /* increase when media is changed. - * used to detect if cached aino is valid - */ - int mountcount; - int mount_changed; - struct zvolume *zarchive; - void *cdfs_superblock; - - TCHAR *mount_volume; - TCHAR *mount_rootdir; - bool mount_readonly; - int mount_flags; - - int reinsertdelay; - TCHAR *newvolume; - TCHAR *newrootdir; - bool newreadonly; - int newflags; - -} Unit; - static uae_u32 a_uniq, key_uniq; #define PUT_PCK_RES1(p,v) do { put_long_host((p)->packet_data + dp_Res1, (v)); } while (0) @@ -2044,8 +2045,8 @@ static uae_u32 filesys_media_change_reply (int mode) flush_cache (u, -1); isofs_unmount (u->ui.cdfs_superblock); ui->cdfs_superblock = u->ui.cdfs_superblock = NULL; - zfile_fclose_archive (u->zarchive); - u->zarchive = NULL; + zfile_fclose_archive (ui->zarchive); + ui->zarchive = NULL; u->ui.unknown_media = false; #ifdef RETROPLATFORM if (ui->unit_type == UNIT_CDFS) @@ -2093,12 +2094,12 @@ static uae_u32 filesys_media_change_reply (int mode) } } } else { - if (set_filesys_volume (u->mount_rootdir, &u->mount_flags, &u->mount_readonly, &emptydrive, &u->zarchive) < 0) + if (set_filesys_volume (u->mount_rootdir, &u->mount_flags, &u->mount_readonly, &emptydrive, &ui->zarchive) < 0) return 0; if (emptydrive) return 0; xfree (u->ui.volname); - ui->volname = u->ui.volname = filesys_createvolname (u->mount_volume, u->mount_rootdir, u->zarchive, _T("removable")); + ui->volname = u->ui.volname = filesys_createvolname (u->mount_volume, u->mount_rootdir, ui->zarchive, _T("removable")); #ifdef RETROPLATFORM rp_harddrive_image_change (nr, u->mount_readonly, u->mount_rootdir); #endif diff --git a/include/zarchive.h b/include/zarchive.h index ffb993d9..9edb8921 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -65,6 +65,7 @@ struct znode { struct zvolume { struct zfile *archive; + bool autofree; void *handle; struct znode root; struct zvolume *next; diff --git a/zfile.cpp b/zfile.cpp index 51b65afe..4cf778ab 100644 --- a/zfile.cpp +++ b/zfile.cpp @@ -3145,7 +3145,11 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename, int flags) } struct zvolume *zfile_fopen_archive (const TCHAR *filename) { - return zfile_fopen_archive (filename, ZFD_ALL); + struct zvolume *zv = zfile_fopen_archive (filename, ZFD_ALL); + if (zv) { + zv->autofree = true; + } + return zv; } struct zvolume *zfile_fopen_archive_root (const TCHAR *filename, int flags) @@ -3222,7 +3226,9 @@ void zfile_fclose_archive (struct zvolume *zv) zn = zn2; } archive_access_close (zv->handle, zv->id); - zfile_fclose(zv->archive); + if (zv->autofree) { + zfile_fclose(zv->archive); + } if (zvolume_list == zv) { zvolume_list = zvolume_list->next; } else { -- 2.47.3