]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Fix zfile stale/double freed file handle.
authorToni Wilen <twilen@winuae.net>
Sun, 31 May 2020 16:47:29 +0000 (19:47 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 31 May 2020 16:47:29 +0000 (19:47 +0300)
filesys.cpp
include/zarchive.h
zfile.cpp

index 6e94e06d0ffa14958ef619770acac7210dae1d0a..570e13d282ca2c6b22707b83ab793d133ead0d55 100644 (file)
@@ -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
index ffb993d95b0fe7c0aeb0ab452ed2acff23a36701..9edb89216d55847f1881ebaaf7605baa09147dd9 100644 (file)
@@ -65,6 +65,7 @@ struct znode {
 struct zvolume
 {
     struct zfile *archive;
+    bool autofree;
     void *handle;
     struct znode root;
     struct zvolume *next;
index 51b65afe8afecab0e610e3319aa2e5330b32dcd8..4cf778abad88768ba4d6276daacf9d3eaf4e18a3 100644 (file)
--- 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 {