DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #ifndef DOSBOX_DOS_SYSTEM_H 00021 #define DOSBOX_DOS_SYSTEM_H 00022 00023 #include <vector> 00024 #ifndef DOSBOX_DOSBOX_H 00025 #include "dosbox.h" 00026 #endif 00027 #ifndef DOSBOX_CROSS_H 00028 #include "cross.h" 00029 #endif 00030 #ifndef DOSBOX_SUPPORT_H 00031 #include "support.h" 00032 #endif 00033 #ifndef DOSBOX_MEM_H 00034 #include "mem.h" 00035 #endif 00036 #include <ctype.h> 00037 00038 #define DOS_NAMELENGTH 12u 00039 #define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) 00040 #define LFN_NAMELENGTH 255u 00041 #define DOS_FCBNAME 15u 00042 #define DOS_DIRDEPTH 8u 00043 #define DOS_PATHLENGTH 255u 00044 #define DOS_TEMPSIZE 1024u 00045 00046 enum { 00047 CPM_COMPAT_OFF=0, 00048 CPM_COMPAT_MSDOS2, 00049 CPM_COMPAT_MSDOS5, 00050 CPM_COMPAT_DIRECT 00051 }; 00052 00053 enum { 00054 DOS_ATTR_READ_ONLY= 0x01, 00055 DOS_ATTR_HIDDEN= 0x02, 00056 DOS_ATTR_SYSTEM= 0x04, 00057 DOS_ATTR_VOLUME= 0x08, 00058 DOS_ATTR_DIRECTORY= 0x10, 00059 DOS_ATTR_ARCHIVE= 0x20, 00060 DOS_ATTR_DEVICE= 0x40 00061 }; 00062 00063 struct FileStat_Block { 00064 Bit32u size; 00065 Bit16u time; 00066 Bit16u date; 00067 Bit16u attr; 00068 }; 00069 00070 class DOS_DTA; 00071 00072 #ifdef WIN32 /* Shaddup MSVC! */ 00073 # define stricmp _stricmp 00074 #endif 00075 00076 class DOS_File { 00077 public: 00078 DOS_File() :flags(0) { name = 0; attr = 0; date = 0; drive = 0; refCtr = 0; open = false; time = 0; hdrive = 0xff; newtime = false; }; 00079 DOS_File(const DOS_File& orig); 00080 DOS_File & operator= (const DOS_File & orig); 00081 virtual ~DOS_File(){if(name) delete [] name;}; 00082 virtual bool Read(Bit8u * data,Bit16u * size)=0; 00083 virtual bool Write(const Bit8u * data,Bit16u * size)=0; 00084 virtual bool Seek(Bit32u * pos,Bit32u type)=0; 00085 virtual bool Close()=0; 00086 /* ert, 20100711: Locking extensions */ 00087 virtual bool LockFile(Bit8u mode, Bit32u pos, Bit16u size) { (void)mode; (void)pos; (void)size; return false; }; 00088 virtual Bit16u GetInformation(void)=0; 00089 virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); } 00090 virtual char* GetName(void) { return name; }; 00091 virtual bool IsOpen() { return open; }; 00092 virtual bool IsName(const char* _name) { if (!name) return false; return strcasecmp(name,_name)==0; }; 00093 virtual void AddRef() { refCtr++; }; 00094 virtual Bits RemoveRef() { return --refCtr; }; 00095 virtual bool UpdateDateTimeFromHost() { return true; } 00096 virtual Bit32u GetSeekPos() { return 0xffffffff; } 00097 void SetDrive(Bit8u drv) { hdrive=drv;} 00098 Bit8u GetDrive(void) { return hdrive;} 00099 virtual void SaveState( std::ostream& stream ); 00100 virtual void LoadState( std::istream& stream, bool pop ); 00101 virtual void Flush(void) { } 00102 00103 char* name = NULL; 00104 Bit8u drive = 0; 00105 Bit32u flags; 00106 bool open; 00107 00108 Bit16u attr; 00109 Bit16u time; 00110 Bit16u date; 00111 Bits refCtr; 00112 bool newtime = false; 00113 /* Some Device Specific Stuff */ 00114 private: 00115 Bit8u hdrive; 00116 }; 00117 00118 class DOS_Device : public DOS_File { 00119 public: 00120 DOS_Device(const DOS_Device& orig):DOS_File(orig) { 00121 devnum=orig.devnum; 00122 open=true; 00123 } 00124 DOS_Device & operator= (const DOS_Device & orig) { 00125 DOS_File::operator=(orig); 00126 devnum=orig.devnum; 00127 open=true; 00128 return *this; 00129 } 00130 DOS_Device():DOS_File(),devnum(0){}; 00131 virtual ~DOS_Device() {}; 00132 virtual bool Read(Bit8u * data,Bit16u * size); 00133 virtual bool Write(const Bit8u * data,Bit16u * size); 00134 virtual bool Seek(Bit32u * pos,Bit32u type); 00135 virtual bool Close(); 00136 virtual Bit16u GetInformation(void); 00137 virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); 00138 virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); 00139 void SetDeviceNumber(Bitu num) { devnum=num;} 00140 private: 00141 Bitu devnum; 00142 }; 00143 00144 class localFile : public DOS_File { 00145 public: 00146 localFile(); 00147 localFile(const char* _name, FILE * handle); 00148 bool Read(Bit8u * data,Bit16u * size); 00149 bool Write(const Bit8u * data,Bit16u * size); 00150 bool Seek(Bit32u * pos,Bit32u type); 00151 bool Close(); 00152 #ifdef WIN32 00153 bool LockFile(Bit8u mode, Bit32u pos, Bit16u size); 00154 #endif 00155 Bit16u GetInformation(void); 00156 bool UpdateDateTimeFromHost(void); 00157 void FlagReadOnlyMedium(void); 00158 void Flush(void); 00159 Bit32u GetSeekPos(void); 00160 FILE * fhandle; 00161 private: 00162 bool read_only_medium; 00163 enum { NONE,READ,WRITE } last_action; 00164 }; 00165 00166 /* The following variable can be lowered to free up some memory. 00167 * The negative side effect: The stored searches will be turned over faster. 00168 * Should not have impact on systems with few directory entries. */ 00169 class DOS_Drive; 00170 #define MAX_OPENDIRS 2048 00171 //Can be high as it's only storage (16 bit variable) 00172 00173 class DOS_Drive_Cache { 00174 public: 00175 DOS_Drive_Cache (void); 00176 DOS_Drive_Cache (const char* path, DOS_Drive *drive); 00177 ~DOS_Drive_Cache (void); 00178 00179 enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; 00180 00181 void SetBaseDir (const char* baseDir, DOS_Drive *drive); 00182 void SetDirSort (TDirSort sort) { sortDirType = sort; }; 00183 bool OpenDir (const char* path, Bit16u& id); 00184 bool ReadDir (Bit16u id, char* &result, char * &lresult); 00185 00186 void ExpandName (char* path); 00187 char* GetExpandName (const char* path); 00188 bool GetShortName (const char* fullname, char* shortname); 00189 00190 bool FindFirst (char* path, Bit16u& id); 00191 bool FindNext (Bit16u id, char* &result, char* &lresult); 00192 00193 void CacheOut (const char* path, bool ignoreLastDir = false); 00194 void AddEntry (const char* path, bool checkExists = false); 00195 void AddEntryDirOverlay (const char* path, char *sfile, bool checkExist = false); 00196 void DeleteEntry (const char* path, bool ignoreLastDir = false); 00197 00198 void EmptyCache (void); 00199 void MediaChange (void); 00200 void SetLabel (const char* vname,bool cdrom,bool allowupdate); 00201 char* GetLabel (void) { return label; }; 00202 00203 class CFileInfo { 00204 public: 00205 CFileInfo(void) { 00206 orgname[0] = shortname[0] = 0; 00207 isOverlayDir = isDir = false; 00208 id = MAX_OPENDIRS; 00209 nextEntry = shortNr = 0; 00210 } 00211 ~CFileInfo(void) { 00212 for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i]; 00213 fileList.clear(); 00214 longNameList.clear(); 00215 }; 00216 char orgname [CROSS_LEN]; 00217 char shortname [DOS_NAMELENGTH_ASCII]; 00218 bool isOverlayDir; 00219 bool isDir; 00220 Bit16u id; 00221 Bitu nextEntry; 00222 Bitu shortNr; 00223 // contents 00224 std::vector<CFileInfo*> fileList; 00225 std::vector<CFileInfo*> longNameList; 00226 }; 00227 00228 private: 00229 void ClearFileInfo(CFileInfo *dir); 00230 void DeleteFileInfo(CFileInfo *dir); 00231 00232 bool RemoveTrailingDot (char* shortname); 00233 Bits GetLongName (CFileInfo* curDir, char* shortName); 00234 void CreateShortName (CFileInfo* curDir, CFileInfo* info); 00235 Bitu CreateShortNameID (CFileInfo* curDir, const char* name); 00236 int CompareShortname (const char* compareName, const char* shortName); 00237 bool SetResult (CFileInfo* dir, char * &result, char * &lresult, Bitu entryNr); 00238 bool IsCachedIn (CFileInfo* curDir); 00239 CFileInfo* FindDirInfo (const char* path, char* expandedPath); 00240 bool RemoveSpaces (char* str); 00241 bool OpenDir (CFileInfo* dir, const char* expand, Bit16u& id); 00242 char* CreateEntry (CFileInfo* dir, const char* name, const char* sname, bool is_directory); 00243 void CopyEntry (CFileInfo* dir, CFileInfo* from); 00244 Bit16u GetFreeID (CFileInfo* dir); 00245 void Clear (void); 00246 00247 CFileInfo* dirBase; 00248 char dirPath [CROSS_LEN] = {}; 00249 DOS_Drive* drive = NULL; 00250 char basePath [CROSS_LEN] = {}; 00251 bool dirFirstTime = false; 00252 TDirSort sortDirType; 00253 CFileInfo* save_dir; 00254 char save_path [CROSS_LEN] = {}; 00255 char save_expanded [CROSS_LEN] = {}; 00256 00257 Bit16u srchNr; 00258 CFileInfo* dirSearch [MAX_OPENDIRS]; 00259 char dirSearchName [MAX_OPENDIRS] = {}; 00260 CFileInfo* dirFindFirst [MAX_OPENDIRS]; 00261 Bit16u nextFreeFindFirst; 00262 00263 char label [CROSS_LEN]; 00264 bool updatelabel; 00265 }; 00266 00267 class DOS_Drive { 00268 public: 00269 DOS_Drive(); 00270 virtual ~DOS_Drive(){}; 00271 virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags)=0; 00272 virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes)=0; 00273 virtual bool FileUnlink(const char * _name)=0; 00274 virtual bool RemoveDir(const char * _dir)=0; 00275 virtual bool MakeDir(const char * _dir)=0; 00276 virtual bool TestDir(const char * _dir)=0; 00277 virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0; 00278 virtual bool FindNext(DOS_DTA & dta)=0; 00279 virtual bool SetFileAttr(const char * name,Bit16u attr)=0; 00280 virtual bool GetFileAttr(const char * name,Bit16u * attr)=0; 00281 virtual bool GetFileAttrEx(char* name, struct stat *status)=0; 00282 virtual unsigned long GetCompressedSize(char* name)=0; 00283 #if defined (WIN32) 00284 virtual HANDLE CreateOpenFile(char const* const name)=0; 00285 #endif 00286 virtual bool Rename(const char * oldname,const char * newname)=0; 00287 virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=0; 00288 virtual bool AllocationInfo32(Bit32u * _bytes_sector,Bit32u * _sectors_cluster,Bit32u * _total_clusters,Bit32u * _free_clusters) { (void)_bytes_sector; (void)_sectors_cluster; (void)_total_clusters; (void)_free_clusters; return false; } 00289 virtual bool FileExists(const char* name)=0; 00290 virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0; 00291 virtual Bit8u GetMediaByte(void)=0; 00292 virtual void SetDir(const char* path) { strcpy(curdir,path); }; 00293 // virtual void EmptyCache(void) { dirCache.EmptyCache(); }; 00294 virtual bool isRemote(void)=0; 00295 virtual bool isRemovable(void)=0; 00296 virtual Bits UnMount(void)=0; 00297 00298 /* these 4 may only be used by DOS_Drive_Cache because they have special calling conventions */ 00299 virtual void *opendir(const char *dir) { (void)dir; return NULL; }; 00300 virtual void closedir(void *handle) { (void)handle; }; 00301 virtual bool read_directory_first(void *handle, char* entry_name, char* entry_sname, bool& is_directory) { (void)handle; (void)entry_name; (void)entry_sname; (void)is_directory; return false; }; 00302 virtual bool read_directory_next(void *handle, char* entry_name, char* entry_sname, bool& is_directory) { (void)handle; (void)entry_name; (void)entry_sname; (void)is_directory; return false; }; 00303 00304 virtual const char * GetInfo(void); 00305 char * GetBaseDir(void); 00306 00307 bool readonly; 00308 bool nocachedir; 00309 char curdir[DOS_PATHLENGTH]; 00310 char info[256]; 00311 /* Can be overridden for example in iso images */ 00312 virtual char const * GetLabel() {return "NOLABEL";}; 00313 virtual void SetLabel(const char *label, bool iscdrom, bool updatable) { (void)label; (void)iscdrom; (void)updatable; }; 00314 virtual void EmptyCache() {}; 00315 virtual void MediaChange() {}; 00316 // disk cycling functionality (request resources) 00317 virtual void Activate(void) {}; 00318 virtual void SaveState( std::ostream& stream ); 00319 virtual void LoadState( std::istream& stream ); 00320 virtual void UpdateDPB(unsigned char dos_drive) { (void)dos_drive; }; 00321 00322 // INT 25h/INT 26h 00323 virtual Bit32u GetSectorCount(void) { return 0; } 00324 virtual Bit32u GetSectorSize(void) { return 0; } // LOGICAL sector size (from the FAT driver) not PHYSICAL disk sector size 00325 virtual Bit8u Read_AbsoluteSector_INT25(Bit32u sectnum, void * data) { (void)sectnum; (void)data; return 0x05; } 00326 virtual Bit8u Write_AbsoluteSector_INT25(Bit32u sectnum, void * data) { (void)sectnum; (void)data; return 0x05; } 00327 }; 00328 00329 enum { OPEN_READ=0, OPEN_WRITE=1, OPEN_READWRITE=2, OPEN_READ_NO_MOD=4, DOS_NOT_INHERIT=128}; 00330 enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; 00331 00332 00333 /* 00334 A multiplex handler should read the registers to check what function is being called 00335 If the handler returns false dos will stop checking other handlers 00336 */ 00337 00338 typedef bool (MultiplexHandler)(void); 00339 void DOS_AddMultiplexHandler(MultiplexHandler * handler); 00340 void DOS_DelMultiplexHandler(MultiplexHandler * handler); 00341 00342 /* AddDevice stores the pointer to a created device */ 00343 void DOS_AddDevice(DOS_Device * adddev); 00344 /* DelDevice destroys the device that is pointed to. */ 00345 void DOS_DelDevice(DOS_Device * dev); 00346 00347 void VFILE_Register(const char * name,Bit8u * data,Bit32u size); 00348 void VFILE_RegisterBuiltinFileBlob(const struct BuiltinFileBlob &b); 00349 #endif