Improve MSCDEX GetDirectoryEntry function: skip associated files, and handle HSF differences in canonicalized structure. Also combine Copyright, Abstract, and Documentation filename functions.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4060
This commit is contained in:
parent
eca070fce9
commit
9857a92c58
1 changed files with 18 additions and 63 deletions
|
@ -113,9 +113,7 @@ public:
|
|||
void GetDrives (PhysPt data);
|
||||
void GetDriverInfo (PhysPt data);
|
||||
bool GetVolumeName (Bit8u subUnit, char* name);
|
||||
bool GetCopyrightName (Bit16u drive, PhysPt data);
|
||||
bool GetAbstractName (Bit16u drive, PhysPt data);
|
||||
bool GetDocumentationName(Bit16u drive, PhysPt data);
|
||||
bool GetFileName (Bit16u drive, Bit16u pos, PhysPt data);
|
||||
bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error);
|
||||
bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& offset, Bit16u& error);
|
||||
bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data);
|
||||
|
@ -620,7 +618,7 @@ bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) {
|
|||
return success;
|
||||
}
|
||||
|
||||
bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) {
|
||||
bool CMscdex::GetFileName(Bit16u drive, Bit16u pos, PhysPt data) {
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
|
@ -628,44 +626,10 @@ bool CMscdex::GetCopyrightName(Bit16u drive, PhysPt data) {
|
|||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+offset+702+len);
|
||||
Bit8u c=mem_readb(ptoc+offset+pos+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+offset+702,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CMscdex::GetAbstractName(Bit16u drive, PhysPt data) {
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+offset+739+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+offset+739,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CMscdex::GetDocumentationName(Bit16u drive, PhysPt data) {
|
||||
Bit16u offset = 0, error;
|
||||
bool success = false;
|
||||
PhysPt ptoc = GetTempBuffer();
|
||||
success = ReadVTOC(drive,0x00,ptoc,offset,error);
|
||||
if (success) {
|
||||
Bitu len;
|
||||
for (len=0;len<37;len++) {
|
||||
Bit8u c=mem_readb(ptoc+offset+776+len);
|
||||
if (c==0 || c==0x20) break;
|
||||
}
|
||||
MEM_BlockCopy(data,ptoc+offset+776,len);
|
||||
MEM_BlockCopy(data,ptoc+offset+pos,len);
|
||||
mem_writeb(data+len,0);
|
||||
};
|
||||
return success;
|
||||
|
@ -724,13 +688,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
PhysPt defBuffer = GetDefaultBuffer();
|
||||
if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false;
|
||||
MEM_StrCopy(defBuffer+1,volumeID,5); volumeID[5] = 0;
|
||||
Bit16u offset;
|
||||
if (strcmp("CD001",volumeID)==0) offset = 156;
|
||||
else {
|
||||
bool iso = (strcmp("CD001",volumeID)==0);
|
||||
if (!iso) {
|
||||
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.");
|
||||
if (strcmp("CDROM",volumeID)!=0) E_Exit("MSCDEX: GetDirEntry: Not an ISO 9660 or HSF CD.");
|
||||
}
|
||||
Bit16u offset = iso ? 156:180;
|
||||
// get directory position
|
||||
Bitu dirEntrySector = mem_readd(defBuffer+offset+2);
|
||||
Bits dirSize = mem_readd(defBuffer+offset+10);
|
||||
|
@ -752,6 +715,11 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
do {
|
||||
entryLength = mem_readb(defBuffer+index);
|
||||
if (entryLength==0) break;
|
||||
if (mem_readb(defBuffer+index+iso ? 0x19:0x18) & 4) {
|
||||
// skip associated files
|
||||
index += entryLength;
|
||||
continue;
|
||||
}
|
||||
nameLength = mem_readb(defBuffer+index+32);
|
||||
MEM_StrCopy(defBuffer+index+33,entryName,nameLength);
|
||||
if (strcmp(entryName,useName)==0) {
|
||||
|
@ -787,8 +755,9 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
memcpy( &writeBuf[1], &readBuf[0x2], 4); // 01h DWORD Logical Block Number of file start
|
||||
writeBuf[5] = 0;writeBuf[6] = 8; // 05h WORD size of disk in logical blocks
|
||||
memcpy( &writeBuf[7], &readBuf[0xa], 4); // 07h DWORD file length in bytes
|
||||
memcpy( &writeBuf[0xb], &readBuf[0x12], 7); // 0bh DWORD date and time
|
||||
writeBuf[0x12] = readBuf[0x19]; // 12h BYTE bit flags
|
||||
memcpy( &writeBuf[0xb], &readBuf[0x12], 6); // 0bh BYTEs date and time
|
||||
writeBuf[0x11] = iso ? readBuf[0x18]:0; // 11h BYTE time zone
|
||||
writeBuf[0x12] = readBuf[iso ? 0x19:0x18]; // 12h BYTE bit flags
|
||||
writeBuf[0x13] = readBuf[0x1a]; // 13h BYTE interleave size
|
||||
writeBuf[0x14] = readBuf[0x1b]; // 14h BYTE interleave skip factor
|
||||
memcpy( &writeBuf[0x15], &readBuf[0x1c], 2); // 15h WORD volume set sequence number
|
||||
|
@ -799,7 +768,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||
// Direct copy
|
||||
MEM_BlockCopy(buffer,defBuffer+index,entryLength);
|
||||
}
|
||||
error = 1;
|
||||
error = iso ? 1:0;
|
||||
return true;
|
||||
}
|
||||
// change directory
|
||||
|
@ -1190,23 +1159,9 @@ static bool MSCDEX_Handler(void) {
|
|||
mscdex->GetDriverInfo(data);
|
||||
return true;
|
||||
case 0x1502: /* Get Copyright filename */
|
||||
if (mscdex->GetCopyrightName(reg_cx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
case 0x1503: /* Get Abstract filename */
|
||||
if (mscdex->GetAbstractName(reg_cx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
case 0x1504: /* Get Documentation filename */
|
||||
if (mscdex->GetDocumentationName(reg_cx,data)) {
|
||||
if (mscdex->GetFileName(reg_cx,702+(reg_al-2)*37,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_ax = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
|
|
Loading…
Add table
Reference in a new issue