DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/dos_system.h
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