openMSX
DirAsDSK.hh
Go to the documentation of this file.
1 #ifndef DIRASDSK_HH
2 #define DIRASDSK_HH
3 
4 #include "SectorBasedDisk.hh"
5 #include "DiskImageUtils.hh"
6 #include "FileOperations.hh"
7 #include "EmuTime.hh"
8 #include <map>
9 
10 namespace openmsx {
11 
12 class DiskChanger;
13 class CliComm;
14 
15 class DirAsDSK final : public SectorBasedDisk
16 {
17 public:
20 
21 public:
22  DirAsDSK(DiskChanger& diskChanger, CliComm& cliComm,
23  const Filename& hostDir, SyncMode syncMode,
24  BootSectorType bootSectorType);
25 
26  // SectorBasedDisk
27  void readSectorImpl (size_t sector, SectorBuffer& buf) override;
28  void writeSectorImpl(size_t sector, const SectorBuffer& buf) override;
29  bool isWriteProtectedImpl() const override;
30  void checkCaches() override;
31 
32 private:
33  struct DirIndex {
34  DirIndex() = default;
35  DirIndex(unsigned sector_, unsigned idx_)
36  : sector(sector_), idx(idx_) {}
37  bool operator<(const DirIndex& rhs) const {
38  if (sector != rhs.sector) return sector < rhs.sector;
39  return idx < rhs.idx;
40  }
41  unsigned sector;
42  unsigned idx;
43  };
44  struct MapDir {
45  std::string hostName; // path relative to 'hostDir'
46  // The following two are used to detect changes in the host
47  // file compared to the last host->virtual-disk sync.
48  time_t mtime; // Modification time of host file at the time of
49  // the last sync.
50  size_t filesize; // Host file size, normally the same as msx
51  // filesize, except when the host file was
52  // truncated.
53  };
54 
55  SectorBuffer* fat();
56  SectorBuffer* fat2();
57  MSXDirEntry& msxDir(DirIndex dirIndex);
58  void writeFATSector (unsigned sector, const SectorBuffer& buf);
59  void writeDIRSector (unsigned sector, DirIndex dirDirIndex,
60  const SectorBuffer& buf);
61  void writeDataSector(unsigned sector, const SectorBuffer& buf);
62  void writeDIREntry(DirIndex dirIndex, DirIndex dirDirIndex,
63  const MSXDirEntry& newEntry);
64  void syncWithHost();
65  void checkDeletedHostFiles();
66  void deleteMSXFile(DirIndex dirIndex);
67  void deleteMSXFilesInDir(unsigned msxDirSector);
68  void freeFATChain(unsigned cluster);
69  void addNewHostFiles(const std::string& hostSubDir, unsigned msxDirSector);
70  void addNewDirectory(const std::string& hostSubDir, const std::string& hostName,
71  unsigned msxDirSector, FileOperations::Stat& fst);
72  void addNewHostFile(const std::string& hostSubDir, const std::string& hostName,
73  unsigned msxDirSector, FileOperations::Stat& fst);
74  DirIndex fillMSXDirEntry(
75  const std::string& hostSubDir, const std::string& hostName,
76  unsigned msxDirSector);
77  DirIndex getFreeDirEntry(unsigned msxDirSector);
78  DirIndex findHostFileInDSK(const std::string& hostName);
79  bool checkFileUsedInDSK(const std::string& hostName);
80  unsigned nextMsxDirSector(unsigned sector);
81  bool checkMSXFileExists(const std::string& msxfilename,
82  unsigned msxDirSector);
83  void checkModifiedHostFiles();
84  void setMSXTimeStamp(DirIndex dirIndex, FileOperations::Stat& fst);
85  void importHostFile(DirIndex dirIndex, FileOperations::Stat& fst);
86  void exportToHost(DirIndex dirIndex, DirIndex dirDirIndex);
87  void exportToHostDir (DirIndex dirIndex, const std::string& hostName);
88  void exportToHostFile(DirIndex dirIndex, const std::string& hostName);
89  unsigned findNextFreeCluster(unsigned cluster);
90  unsigned findFirstFreeCluster();
91  unsigned getFreeCluster();
92  unsigned readFAT(unsigned cluster);
93  void writeFAT12(unsigned cluster, unsigned val);
94  void exportFileFromFATChange(unsigned cluster, SectorBuffer* oldFAT);
95  unsigned getChainStart(unsigned cluster, unsigned& chainLength);
96  bool isDirSector(unsigned sector, DirIndex& dirDirIndex);
97  bool getDirEntryForCluster(unsigned cluster,
98  DirIndex& dirIndex, DirIndex& dirDirIndex);
99  DirIndex getDirEntryForCluster(unsigned cluster);
100  void unmapHostFiles(unsigned msxDirSector);
101  template<typename FUNC> bool scanMsxDirs(
102  FUNC func, unsigned msxDirSector);
103  friend struct NullScanner;
104  friend struct DirScanner;
105  friend struct IsDirSector;
106  friend struct DirEntryForCluster;
107  friend struct UnmapHostFiles;
108 
109  // internal helper functions
110  unsigned readFATHelper(const SectorBuffer* fat, unsigned cluster) const;
111  void writeFATHelper(SectorBuffer* fat, unsigned cluster, unsigned val) const;
112  unsigned clusterToSector(unsigned cluster) const;
113  void sectorToCluster(unsigned sector, unsigned& cluster, unsigned& offset) const;
114  unsigned sectorToCluster(unsigned sector) const;
115 
116 private:
117  DiskChanger& diskChanger; // used to query time / report disk change
118  CliComm& cliComm; // TODO don't use CliComm to report errors/warnings
119  const std::string hostDir;
120  const SyncMode syncMode;
121 
122  EmuTime lastAccess; // last time there was a sector read/write
123 
124  // For each directory entry that has a mapped host file/directory we
125  // store the name, last modification time and size of the corresponding
126  // host file/dir.
127  using MapDirs = std::map<DirIndex, MapDir>;
128  MapDirs mapDirs;
129 
130  // format parameters which depend on single/double sided
131  // varying root parameters
132  const unsigned nofSectors;
133  const unsigned nofSectorsPerFat;
134  // parameters that depend on these and thus also vary
135  const unsigned firstSector2ndFAT;
136  const unsigned firstDirSector;
137  const unsigned firstDataSector;
138  const unsigned maxCluster; // First cluster number that can NOT be used anymore.
139 
140  // Storage for the whole virtual disk.
141  std::vector<SectorBuffer> sectors;
142 };
143 
144 } // namespace openmsx
145 
146 #endif
Abstract class for disk images that only represent the logical sector information (so not the raw tra...
DirAsDSK(DiskChanger &diskChanger, CliComm &cliComm, const Filename &hostDir, SyncMode syncMode, BootSectorType bootSectorType)
Definition: DirAsDSK.cc:260
void writeSectorImpl(size_t sector, const SectorBuffer &buf) override
Definition: DirAsDSK.cc:890
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
constexpr bool operator<(const optional< T > &x, const optional< T > &y)
Definition: optional.hh:515
void checkCaches() override
Definition: DirAsDSK.cc:332
void readSectorImpl(size_t sector, SectorBuffer &buf) override
Definition: DirAsDSK.cc:350
bool isWriteProtectedImpl() const override
Definition: DirAsDSK.cc:327