DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/dos/drives.h
00001 /*
00002  *  Copyright (C) 2002-2015  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
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 #ifndef _DRIVES_H__
00021 #define _DRIVES_H__
00022 
00023 #include <vector>
00024 #include <sys/types.h>
00025 #include "dos_system.h"
00026 #include "shell.h" /* for DOS_Shell */
00027 
00028 bool WildFileCmp(const char * file, const char * wild);
00029 void Set_Label(char const * const input, char * const output, bool cdrom);
00030 
00031 class DriveManager {
00032 public:
00033         static void AppendDisk(int drive, DOS_Drive* disk);
00034         static void InitializeDrive(int drive);
00035         static int UnmountDrive(int drive);
00036 //      static void CycleDrive(bool pressed);
00037 //      static void CycleDisk(bool pressed);
00038         static void CycleAllDisks(void);
00039         static void CycleAllCDs(void);
00040         static void Init(Section* sec);
00041         
00042         static void SaveState( std::ostream& stream );
00043         static void LoadState( std::istream& stream );
00044         
00045 private:
00046         static struct DriveInfo {
00047                 std::vector<DOS_Drive*> disks;
00048                 Bit32u currentDisk;
00049         } driveInfos[DOS_DRIVES];
00050         
00051         static int currentDrive;
00052 };
00053 
00054 class localDrive : public DOS_Drive {
00055 public:
00056         localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
00057         virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00058         virtual FILE *GetSystemFilePtr(char const * const name, char const * const type); 
00059         virtual bool GetSystemFilename(char* sysName, char const * const dosName); 
00060         virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00061         virtual bool FileUnlink(const char * name);
00062         virtual bool RemoveDir(const char * dir);
00063         virtual bool MakeDir(const char * dir);
00064         virtual bool TestDir(const char * dir);
00065         virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false);
00066         virtual bool FindNext(DOS_DTA & dta);
00067         virtual bool GetFileAttr(const char * name,Bit16u * attr);
00068         virtual bool Rename(const char * oldname,const char * newname);
00069         virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
00070         virtual bool FileExists(const char* name);
00071         virtual bool FileStat(const char* name, FileStat_Block * const stat_block);
00072         virtual Bit8u GetMediaByte(void);
00073         virtual bool isRemote(void);
00074         virtual bool isRemovable(void);
00075         virtual Bits UnMount(void);
00076         virtual char const * GetLabel(){return dirCache.GetLabel();};
00077         virtual void SetLabel(const char *label, bool iscdrom, bool updatable) { dirCache.SetLabel(label,iscdrom,updatable); };
00078         virtual void *opendir(const char *dir);
00079         virtual void closedir(void *handle);
00080         virtual bool read_directory_first(void *handle, char* entry_name, bool& is_directory);
00081         virtual bool read_directory_next(void *handle, char* entry_name, bool& is_directory);
00082 
00083         virtual void EmptyCache(void) { dirCache.EmptyCache(); };
00084         virtual void MediaChange() {};
00085 
00086 protected:
00087         DOS_Drive_Cache dirCache;
00088         char basedir[CROSS_LEN];
00089         friend void DOS_Shell::CMD_SUBST(char* args);   
00090         struct {
00091                 char srch_dir[CROSS_LEN];
00092         } srchInfo[MAX_OPENDIRS];
00093 
00094         struct {
00095                 Bit16u bytes_sector;
00096                 Bit8u sectors_cluster;
00097                 Bit16u total_clusters;
00098                 Bit16u free_clusters;
00099                 Bit8u mediaid;
00100         } allocation;
00101 };
00102 
00103 class physfsDrive : public localDrive {
00104 private:
00105         bool isdir(const char *dir);
00106 
00107 public:
00108         physfsDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
00109         virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00110         virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00111         virtual bool FileUnlink(const char * name);
00112         virtual bool RemoveDir(const char * dir);
00113         virtual bool MakeDir(const char * dir);
00114         virtual bool TestDir(const char * dir);
00115         virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false);
00116         virtual bool FindNext(DOS_DTA & dta);
00117         virtual bool GetFileAttr(const char * name,Bit16u * attr);
00118         virtual bool Rename(const char * oldname,const char * newname);
00119         virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
00120         virtual bool FileExists(const char* name);
00121         virtual bool FileStat(const char* name, FileStat_Block * const stat_block);
00122         virtual Bit8u GetMediaByte(void);
00123         virtual bool isRemote(void);
00124         virtual bool isRemovable(void);
00125         virtual void *opendir(const char *dir);
00126         virtual void closedir(void *handle);
00127         virtual bool read_directory_first(void *handle, char* entry_name, bool& is_directory);
00128         virtual bool read_directory_next(void *handle, char* entry_name, bool& is_directory);
00129         virtual const char *GetInfo(void);
00130         virtual ~physfsDrive(void);
00131 };
00132 
00133 #ifdef _MSC_VER
00134 #pragma pack (1)
00135 #endif
00136 struct bootstrap {
00137         Bit8u  nearjmp[3];
00138         Bit8u  oemname[8];
00139         Bit16u bytespersector;
00140         Bit8u  sectorspercluster;
00141         Bit16u reservedsectors;
00142         Bit8u  fatcopies;
00143         Bit16u rootdirentries;
00144         Bit16u totalsectorcount;
00145         Bit8u  mediadescriptor;
00146         Bit16u sectorsperfat;
00147         Bit16u sectorspertrack;
00148         Bit16u headcount;
00149         /* 32-bit FAT extensions */
00150         Bit32u hiddensectorcount;
00151         Bit32u totalsecdword;
00152         Bit8u  bootcode[474];
00153         Bit8u  magic1; /* 0x55 */
00154         Bit8u  magic2; /* 0xaa */
00155 #ifndef SECTOR_SIZE_MAX
00156 # pragma warning SECTOR_SIZE_MAX not defined
00157 #endif
00158 #if SECTOR_SIZE_MAX > 512
00159     Bit8u  extra[SECTOR_SIZE_MAX - 512];
00160 #endif
00161 } GCC_ATTRIBUTE(packed);
00162 
00163 struct direntry {
00164         Bit8u entryname[11];
00165         Bit8u attrib;
00166         Bit8u NTRes;
00167         Bit8u milliSecondStamp;
00168         Bit16u crtTime;
00169         Bit16u crtDate;
00170         Bit16u accessDate;
00171         Bit16u hiFirstClust;
00172         Bit16u modTime;
00173         Bit16u modDate;
00174         Bit16u loFirstClust;
00175         Bit32u entrysize;
00176 } GCC_ATTRIBUTE(packed);
00177 
00178 #define MAX_DIRENTS_PER_SECTOR (SECTOR_SIZE_MAX / sizeof(direntry))
00179 
00180 struct partTable {
00181         Bit8u booter[446];
00182         struct {
00183                 Bit8u bootflag;
00184                 Bit8u beginchs[3];
00185                 Bit8u parttype;
00186                 Bit8u endchs[3];
00187                 Bit32u absSectStart;
00188                 Bit32u partSize;
00189         } pentry[4];
00190         Bit8u  magic1; /* 0x55 */
00191         Bit8u  magic2; /* 0xaa */
00192 #ifndef SECTOR_SIZE_MAX
00193 # pragma warning SECTOR_SIZE_MAX not defined
00194 #endif
00195 #if SECTOR_SIZE_MAX > 512
00196     Bit8u  extra[SECTOR_SIZE_MAX - 512];
00197 #endif
00198 } GCC_ATTRIBUTE(packed);
00199 
00200 #ifdef _MSC_VER
00201 #pragma pack ()
00202 #endif
00203 //Forward
00204 class imageDisk;
00205 class fatDrive : public DOS_Drive {
00206 public:
00207         fatDrive(const char * sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders);
00208         fatDrive(imageDisk *sourceLoadedDisk);
00209     void fatDriveInit(const char *sysFilename, Bit32u bytesector, Bit32u cylsector, Bit32u headscyl, Bit32u cylinders, Bit64u filesize);
00210     virtual ~fatDrive();
00211         virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00212         virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00213         virtual bool FileUnlink(const char * name);
00214         virtual bool RemoveDir(const char * dir);
00215         virtual bool MakeDir(const char * dir);
00216         virtual bool TestDir(const char * dir);
00217         virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false);
00218         virtual bool FindNext(DOS_DTA & dta);
00219         virtual bool GetFileAttr(const char * name,Bit16u * attr);
00220         virtual bool Rename(const char * oldname,const char * newname);
00221         virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
00222         virtual bool FileExists(const char* name);
00223         virtual bool FileStat(const char* name, FileStat_Block * const stat_block);
00224         virtual Bit8u GetMediaByte(void);
00225         virtual bool isRemote(void);
00226         virtual bool isRemovable(void);
00227         virtual Bits UnMount(void);
00228 public:
00229         Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos);
00230         Bit32u getSectorSize(void);
00231         Bit32u getAbsoluteSectFromChain(Bit32u startClustNum, Bit32u logicalSector);
00232         bool allocateCluster(Bit32u useCluster, Bit32u prevCluster);
00233         Bit32u appendCluster(Bit32u startCluster);
00234         void deleteClustChain(Bit32u startCluster);
00235         Bit32u getFirstFreeClust(void);
00236         bool directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum, Bit32s start=0);
00237         bool directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s entNum);
00238         imageDisk *loadedDisk;
00239         bool created_successfully;
00240 private:
00241         Bit32u getClusterValue(Bit32u clustNum);
00242         void setClusterValue(Bit32u clustNum, Bit32u clustValue);
00243         Bit32u getClustFirstSect(Bit32u clustNum);
00244         bool FindNextInternal(Bit32u dirClustNumber, DOS_DTA & dta, direntry *foundEntry);
00245         bool getDirClustNum(const char * dir, Bit32u * clustNum, bool parDir);
00246         bool getFileDirEntry(char const * const filename, direntry * useEntry, Bit32u * dirClust, Bit32u * subEntry);
00247         bool addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry);
00248         void zeroOutCluster(Bit32u clustNumber);
00249         bool getEntryName(const char *fullname, char *entname);
00250         friend void DOS_Shell::CMD_SUBST(char* args);   
00251         struct {
00252                 char srch_dir[CROSS_LEN];
00253         } srchInfo[MAX_OPENDIRS];
00254 
00255         struct {
00256                 Bit16u bytes_sector;
00257                 Bit8u sectors_cluster;
00258                 Bit16u total_clusters;
00259                 Bit16u free_clusters;
00260                 Bit8u mediaid;
00261         } allocation;
00262         
00263         bootstrap bootbuffer;
00264         Bit8u fattype;
00265         Bit32u CountOfClusters;
00266         Bit32u partSectOff;
00267         Bit32u firstDataSector;
00268         Bit32u firstRootDirSect;
00269 
00270         Bit32u cwdDirCluster;
00271         Bit32u dirPosition; /* Position in directory search */
00272 
00273         Bit8u fatSectBuffer[SECTOR_SIZE_MAX * 2];
00274         Bit32u curFatSect;
00275 public:
00276     /* the driver code must use THESE functions to read the disk, not directly from the disk drive,
00277      * in order to support a drive with a smaller sector size than the FAT filesystem's "sector".
00278      *
00279      * It is very common for instance to have PC-98 HDI images formatted with 256 bytes/sector at
00280      * the disk level and a FAT filesystem marked as having 1024 bytes/sector. */
00281         virtual Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
00282         virtual Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
00283         virtual Bit32u getSectSize(void);
00284         Bit32u sector_size;
00285 };
00286 
00287 
00288 class cdromDrive : public localDrive
00289 {
00290 public:
00291         cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error);
00292         virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00293         virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00294         virtual bool FileUnlink(const char * name);
00295         virtual bool RemoveDir(const char * dir);
00296         virtual bool MakeDir(const char * dir);
00297         virtual bool Rename(const char * oldname,const char * newname);
00298         virtual bool GetFileAttr(const char * name,Bit16u * attr);
00299         virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false);
00300         virtual void SetDir(const char* path);
00301         virtual bool isRemote(void);
00302         virtual bool isRemovable(void);virtual Bits UnMount(void);
00303 private:
00304         Bit8u subUnit;  char driveLetter;
00305 };
00306 
00307 class physfscdromDrive : public physfsDrive
00308 {
00309 public:
00310         physfscdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error);
00311         virtual bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00312         virtual bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00313         virtual bool FileUnlink(const char * name);
00314         virtual bool RemoveDir(const char * dir);
00315         virtual bool MakeDir(const char * dir);
00316         virtual bool Rename(const char * oldname,const char * newname);
00317         virtual bool GetFileAttr(const char * name,Bit16u * attr);
00318         virtual bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst=false);
00319         virtual void SetDir(const char* path);
00320         virtual bool isRemote(void);
00321         virtual bool isRemovable(void);
00322         virtual Bits UnMount(void);
00323         virtual const char *GetInfo(void);
00324 private:
00325         Bit8u subUnit;
00326         char driveLetter;
00327 };
00328 
00329 #ifdef _MSC_VER
00330 #pragma pack (1)
00331 #endif
00332 struct isoPVD {
00333         Bit8u type;
00334         Bit8u standardIdent[5];
00335         Bit8u version;
00336         Bit8u unused1;
00337         Bit8u systemIdent[32];
00338         Bit8u volumeIdent[32];
00339         Bit8u unused2[8];
00340         Bit32u volumeSpaceSizeL;
00341         Bit32u volumeSpaceSizeM;
00342         Bit8u unused3[32];
00343         Bit16u volumeSetSizeL;
00344         Bit16u volumeSetSizeM;
00345         Bit16u volumeSeqNumberL;
00346         Bit16u volumeSeqNumberM;
00347         Bit16u logicBlockSizeL;
00348         Bit16u logicBlockSizeM;
00349         Bit32u pathTableSizeL;
00350         Bit32u pathTableSizeM;
00351         Bit32u locationPathTableL;
00352         Bit32u locationOptPathTableL;
00353         Bit32u locationPathTableM;
00354         Bit32u locationOptPathTableM;
00355         Bit8u rootEntry[34];
00356         Bit32u unused4[1858];
00357 } GCC_ATTRIBUTE(packed);
00358 
00359 struct isoDirEntry {
00360         Bit8u length;
00361         Bit8u extAttrLength;
00362         Bit32u extentLocationL;
00363         Bit32u extentLocationM;
00364         Bit32u dataLengthL;
00365         Bit32u dataLengthM;
00366         Bit8u dateYear;
00367         Bit8u dateMonth;
00368         Bit8u dateDay;
00369         Bit8u timeHour;
00370         Bit8u timeMin;
00371         Bit8u timeSec;
00372         Bit8u timeZone;
00373         Bit8u fileFlags;
00374         Bit8u fileUnitSize;
00375         Bit8u interleaveGapSize;
00376         Bit16u VolumeSeqNumberL;
00377         Bit16u VolumeSeqNumberM;
00378         Bit8u fileIdentLength;
00379         Bit8u ident[222];
00380 } GCC_ATTRIBUTE(packed);
00381 
00382 #ifdef _MSC_VER
00383 #pragma pack ()
00384 #endif
00385 
00386 #if defined (WORDS_BIGENDIAN)
00387 #define EXTENT_LOCATION(de)     ((de).extentLocationM)
00388 #define DATA_LENGTH(de)         ((de).dataLengthM)
00389 #else
00390 #define EXTENT_LOCATION(de)     ((de).extentLocationL)
00391 #define DATA_LENGTH(de)         ((de).dataLengthL)
00392 #endif
00393 
00394 #define ISO_FRAMESIZE           2048u
00395 #define ISO_ASSOCIATED          4u
00396 #define ISO_DIRECTORY           2u
00397 #define ISO_HIDDEN              1u
00398 #define ISO_MAX_FILENAME_LENGTH 37u
00399 #define ISO_MAXPATHNAME         256u
00400 #define ISO_FIRST_VD            16u
00401 #define IS_ASSOC(fileFlags)     (fileFlags & ISO_ASSOCIATED)
00402 #define IS_DIR(fileFlags)       (fileFlags & ISO_DIRECTORY)
00403 #define IS_HIDDEN(fileFlags)    (fileFlags & ISO_HIDDEN)
00404 #define ISO_MAX_HASH_TABLE_SIZE         100u
00405 
00406 class isoDrive : public DOS_Drive {
00407 public:
00408         isoDrive(char driveLetter, const char* device_name, Bit8u mediaid, int &error);
00409         ~isoDrive();
00410         virtual bool FileOpen(DOS_File **file, const char *name, Bit32u flags);
00411         virtual bool FileCreate(DOS_File **file, const char *name, Bit16u attributes);
00412         virtual bool FileUnlink(const char *name);
00413         virtual bool RemoveDir(const char *dir);
00414         virtual bool MakeDir(const char *dir);
00415         virtual bool TestDir(const char *dir);
00416         virtual bool FindFirst(const char *_dir, DOS_DTA &dta, bool fcb_findfirst);
00417         virtual bool FindNext(DOS_DTA &dta);
00418         virtual bool GetFileAttr(const char *name, Bit16u *attr);
00419         virtual bool Rename(const char * oldname,const char * newname);
00420         virtual bool AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters);
00421         virtual bool FileExists(const char *name);
00422         virtual bool FileStat(const char *name, FileStat_Block *const stat_block);
00423         virtual Bit8u GetMediaByte(void);
00424         virtual void EmptyCache(void){}
00425         virtual void MediaChange();
00426         virtual bool isRemote(void);
00427         virtual bool isRemovable(void);
00428         virtual Bits UnMount(void);
00429         bool readSector(Bit8u *buffer, Bit32u sector);
00430         virtual char const* GetLabel(void) {return discLabel;};
00431         virtual void Activate(void);
00432 private:
00433         int  readDirEntry(isoDirEntry *de, Bit8u *data);
00434         bool loadImage();
00435         bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length);
00436         bool lookup(isoDirEntry *de, const char *path);
00437         int  UpdateMscdex(char driveLetter, const char* physicalPath, Bit8u& subUnit);
00438         int  GetDirIterator(const isoDirEntry* de);
00439         bool GetNextDirEntry(const int dirIterator, isoDirEntry* de);
00440         void FreeDirIterator(const int dirIterator);
00441         bool ReadCachedSector(Bit8u** buffer, const Bit32u sector);
00442         
00443         struct DirIterator {
00444                 bool valid;
00445                 bool root;
00446                 Bit32u currentSector;
00447                 Bit32u endSector;
00448                 Bit32u pos;
00449         } dirIterators[MAX_OPENDIRS];
00450         
00451         int nextFreeDirIterator;
00452         
00453         struct SectorHashEntry {
00454                 bool valid;
00455                 Bit32u sector;
00456                 Bit8u data[ISO_FRAMESIZE];
00457         } sectorHashEntries[ISO_MAX_HASH_TABLE_SIZE];
00458 
00459         bool iso;
00460         bool dataCD;
00461         isoDirEntry rootEntry;
00462         Bit8u mediaid;
00463         char fileName[CROSS_LEN];
00464         Bit8u subUnit;
00465         char driveLetter;
00466         char discLabel[32];
00467 };
00468 
00469 struct VFILE_Block;
00470 
00471 class Virtual_Drive: public DOS_Drive {
00472 public:
00473         Virtual_Drive();
00474         bool FileOpen(DOS_File * * file,const char * name,Bit32u flags);
00475         bool FileCreate(DOS_File * * file,const char * name,Bit16u attributes);
00476         bool FileUnlink(const char * name);
00477         bool RemoveDir(const char * dir);
00478         bool MakeDir(const char * dir);
00479         bool TestDir(const char * dir);
00480         bool FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst);
00481         bool FindNext(DOS_DTA & dta);
00482         bool GetFileAttr(const char * name,Bit16u * attr);
00483         bool Rename(const char * oldname,const char * newname);
00484         bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
00485         bool FileExists(const char* name);
00486         bool FileStat(const char* name, FileStat_Block* const stat_block);
00487         virtual void MediaChange() {}
00488         Bit8u GetMediaByte(void);
00489         void EmptyCache(void){}
00490         bool isRemote(void);
00491         virtual bool isRemovable(void);
00492         virtual Bits UnMount(void);
00493 private:
00494         VFILE_Block * search_file;
00495 };
00496 
00497 
00498 
00499 #endif