1
0
Fork 0

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:
ripsaw8080 2017-10-28 19:47:09 +00:00
parent eca070fce9
commit 9857a92c58

View file

@ -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;