Add support for High Sierra format cdrom images.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3886
This commit is contained in:
parent
56c3a4be9c
commit
933174fb3e
4 changed files with 64 additions and 47 deletions
|
@ -416,8 +416,9 @@ bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mod
|
|||
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
|
||||
if (mode2) seek += 24;
|
||||
file->read(pvd, seek, COOKED_SECTOR_SIZE);
|
||||
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version
|
||||
return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1);
|
||||
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra)
|
||||
return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) ||
|
||||
(pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1));
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
bool GetAbstractName (Bit16u drive, PhysPt data);
|
||||
bool GetDocumentationName(Bit16u drive, PhysPt data);
|
||||
bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error);
|
||||
bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error);
|
||||
bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error);
|
||||
bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
|
||||
|
@ -577,7 +577,7 @@ Bit32u CMscdex::GetVolumeSize(Bit8u subUnit) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) {
|
||||
bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error) {
|
||||
Bit8u subunit = GetSubUnit(drive);
|
||||
/* if (subunit>=numDrives) {
|
||||
error=MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
|
@ -589,11 +589,16 @@ bool CMscdex::ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error)
|
|||
}
|
||||
char id[5];
|
||||
MEM_BlockRead(data + 1, id, 5);
|
||||
if (strncmp("CD001",id, 5)!=0) {
|
||||
error = MSCDEX_ERROR_BAD_FORMAT;
|
||||
return false;
|
||||
if (strncmp("CD001", id, 5)==0) offset = 0;
|
||||
else {
|
||||
MEM_BlockRead(data + 9, id, 5);
|
||||
if (strncmp("CDROM", id, 5)==0) offset = 8;
|
||||
else {
|
||||
error = MSCDEX_ERROR_BAD_FORMAT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Bit8u type = mem_readb(data);
|
||||
Bit8u type = mem_readb(data + offset);
|
||||
error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -602,12 +607,12 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) {
|
|||
if (subUnit>=numDrives) return false;
|
||||
Bit16u drive = dinfo[subUnit].drive;
|
||||
|
||||
Bit16u error;
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,error);
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
MEM_StrCopy(ptoc+40,data,31);
|
||||
MEM_StrCopy(ptoc+offset+40,data,31);
|
||||
data[31] = 0;
|
||||
rtrim(data);
|
||||
};
|
||||
|
@ -616,51 +621,51 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) {
|
|||
}
|
||||
|
||||
bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) {
|
||||
Bit16u error;
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,error);
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+702+len);
|
||||
Bit8u c=mem_readb(ptoc+offset+702+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+702,len);
|
||||
MEM_BlockCopy(data,ptoc+offset+702,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) {
|
||||
Bit16u error;
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,error);
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+739+len);
|
||||
Bit8u c=mem_readb(ptoc+offset+739+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+739,len);
|
||||
MEM_BlockCopy(data,ptoc+offset+739,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) {
|
||||
Bit16u error;
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,error);
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+776+len);
|
||||
Bit8u c=mem_readb(ptoc+offset+776+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+776,len);
|
||||
MEM_BlockCopy(data,ptoc+offset+776,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
|
@ -718,13 +723,17 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
// read vtoc
|
||||
PhysPt defBuffer = GetDefaultBuffer();
|
||||
if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false;
|
||||
// TODO: has to be iso 9960
|
||||
MEM_StrCopy(defBuffer+1,volumeID,5); volumeID[5] = 0;
|
||||
bool iso = (strcmp("CD001",volumeID)==0);
|
||||
if (!iso) E_Exit("MSCDEX: GetDirEntry: Not an ISO 9960 CD.");
|
||||
Bit16u offset;
|
||||
if (strcmp("CD001",volumeID)==0) offset = 156;
|
||||
else {
|
||||
MEM_StrCopy(defBuffer+9,volumeID,5);
|
||||
if (strcmp("CDROM",volumeID)==0) offset = 180;
|
||||
else E_Exit("MSCDEX: GetDirEntry: Not an ISO 9660 or High Sierra CD.");
|
||||
}
|
||||
// get directory position
|
||||
Bitu dirEntrySector = mem_readd(defBuffer+156+2);
|
||||
Bits dirSize = mem_readd(defBuffer+156+10);
|
||||
Bitu dirEntrySector = mem_readd(defBuffer+offset+2);
|
||||
Bits dirSize = mem_readd(defBuffer+offset+10);
|
||||
Bitu index;
|
||||
while (dirSize>0) {
|
||||
index = 0;
|
||||
|
@ -790,7 +799,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
// Direct copy
|
||||
MEM_BlockCopy(buffer,defBuffer+index,entryLength);
|
||||
}
|
||||
error = iso ? 1:0;
|
||||
error = 1;
|
||||
return true;
|
||||
}
|
||||
// change directory
|
||||
|
@ -1203,8 +1212,8 @@ static bool MSCDEX_Handler(void) {
|
|||
};
|
||||
return true;
|
||||
case 0x1505: { // read vtoc
|
||||
Bit16u error = 0;
|
||||
if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) {
|
||||
Bit16u offset = 0, error = 0;
|
||||
if (mscdex->ReadVTOC(reg_cx,reg_dx,data,offset,error)) {
|
||||
// reg_ax = error; // return code
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "support.h"
|
||||
#include "drives.h"
|
||||
|
||||
#define FLAGS1 ((iso) ? de.fileFlags : de.timeZone)
|
||||
#define FLAGS2 ((iso) ? de->fileFlags : de->timeZone)
|
||||
|
||||
using namespace std;
|
||||
|
||||
class isoFile : public DOS_File {
|
||||
|
@ -198,7 +201,7 @@ bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) {
|
|||
}
|
||||
|
||||
isoDirEntry de;
|
||||
bool success = lookup(&de, name) && !IS_DIR(de.fileFlags);
|
||||
bool success = lookup(&de, name) && !IS_DIR(FLAGS1);
|
||||
|
||||
if (success) {
|
||||
FileStat_Block file_stat;
|
||||
|
@ -234,7 +237,7 @@ bool isoDrive::MakeDir(char* /*dir*/) {
|
|||
|
||||
bool isoDrive::TestDir(char *dir) {
|
||||
isoDirEntry de;
|
||||
return (lookup(&de, dir) && IS_DIR(de.fileFlags));
|
||||
return (lookup(&de, dir) && IS_DIR(FLAGS1));
|
||||
}
|
||||
|
||||
bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) {
|
||||
|
@ -279,11 +282,11 @@ bool isoDrive::FindNext(DOS_DTA &dta) {
|
|||
isoDirEntry de;
|
||||
while (GetNextDirEntry(dirIterator, &de)) {
|
||||
Bit8u findAttr = 0;
|
||||
if (IS_DIR(de.fileFlags)) findAttr |= DOS_ATTR_DIRECTORY;
|
||||
if (IS_DIR(FLAGS1)) findAttr |= DOS_ATTR_DIRECTORY;
|
||||
else findAttr |= DOS_ATTR_ARCHIVE;
|
||||
if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN;
|
||||
if (IS_HIDDEN(FLAGS1)) findAttr |= DOS_ATTR_HIDDEN;
|
||||
|
||||
if (!IS_ASSOC(de.fileFlags) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern)
|
||||
if (!IS_ASSOC(FLAGS1) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern)
|
||||
&& !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) {
|
||||
|
||||
/* file is okay, setup everything to be copied in DTA Block */
|
||||
|
@ -318,8 +321,8 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr) {
|
|||
bool success = lookup(&de, name);
|
||||
if (success) {
|
||||
*attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY;
|
||||
if (IS_HIDDEN(de.fileFlags)) *attr |= DOS_ATTR_HIDDEN;
|
||||
if (IS_DIR(de.fileFlags)) *attr |= DOS_ATTR_DIRECTORY;
|
||||
if (IS_HIDDEN(FLAGS1)) *attr |= DOS_ATTR_HIDDEN;
|
||||
if (IS_DIR(FLAGS1)) *attr |= DOS_ATTR_DIRECTORY;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -334,7 +337,7 @@ bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit1
|
|||
|
||||
bool isoDrive::FileExists(const char *name) {
|
||||
isoDirEntry de;
|
||||
return (lookup(&de, name) && !IS_DIR(de.fileFlags));
|
||||
return (lookup(&de, name) && !IS_DIR(FLAGS1));
|
||||
}
|
||||
|
||||
bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) {
|
||||
|
@ -346,7 +349,7 @@ bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) {
|
|||
stat_block->time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec);
|
||||
stat_block->size = DATA_LENGTH(de);
|
||||
stat_block->attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY;
|
||||
if (IS_DIR(de.fileFlags)) stat_block->attr |= DOS_ATTR_DIRECTORY;
|
||||
if (IS_DIR(FLAGS1)) stat_block->attr |= DOS_ATTR_DIRECTORY;
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -470,7 +473,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) {
|
|||
|
||||
// modify file identifier for use with dosbox
|
||||
if ((de->length < 33 + de->fileIdentLength)) return -1;
|
||||
if (IS_DIR(de->fileFlags)) {
|
||||
if (IS_DIR(FLAGS2)) {
|
||||
if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, ".");
|
||||
else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, "..");
|
||||
else {
|
||||
|
@ -499,11 +502,14 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) {
|
|||
}
|
||||
|
||||
bool isoDrive :: loadImage() {
|
||||
isoPVD pvd;
|
||||
Bit8u pvd[COOKED_SECTOR_SIZE];
|
||||
dataCD = false;
|
||||
readSector((Bit8u*)(&pvd), ISO_FIRST_VD);
|
||||
if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false;
|
||||
if (readDirEntry(&this->rootEntry, pvd.rootEntry)>0) {
|
||||
readSector(pvd, ISO_FIRST_VD);
|
||||
if (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) iso = true;
|
||||
else if (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1) iso = false;
|
||||
else return false;
|
||||
Bit16u offset = iso ? 156 : 180;
|
||||
if (readDirEntry(&this->rootEntry, &pvd[offset])>0) {
|
||||
dataCD = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -524,7 +530,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) {
|
|||
|
||||
bool found = false;
|
||||
// current entry must be a directory, abort otherwise
|
||||
if (IS_DIR(de->fileFlags)) {
|
||||
if (IS_DIR(FLAGS2)) {
|
||||
|
||||
// remove the trailing dot if present
|
||||
size_t nameLength = strlen(name);
|
||||
|
@ -535,7 +541,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) {
|
|||
// look for the current path element
|
||||
int dirIterator = GetDirIterator(de);
|
||||
while (!found && GetNextDirEntry(dirIterator, de)) {
|
||||
if (!IS_ASSOC(de->fileFlags) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) {
|
||||
if (!IS_ASSOC(FLAGS2) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,6 +363,7 @@ private:
|
|||
Bit8u data[ISO_FRAMESIZE];
|
||||
} sectorHashEntries[ISO_MAX_HASH_TABLE_SIZE];
|
||||
|
||||
bool iso;
|
||||
bool dataCD;
|
||||
isoDirEntry rootEntry;
|
||||
Bit8u mediaid;
|
||||
|
|
Loading…
Add table
Reference in a new issue