added mscdex function 0f : Get directory entry
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1511
This commit is contained in:
parent
99b81667e5
commit
4a8f40c92d
1 changed files with 98 additions and 2 deletions
|
@ -109,6 +109,7 @@ public:
|
|||
bool GetCopyrightName (Bit16u drive, PhysPt data);
|
||||
bool GetAbstractName (Bit16u drive, PhysPt data);
|
||||
bool GetDocumentationName(Bit16u drive, PhysPt data);
|
||||
bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bitu& error);
|
||||
bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error);
|
||||
bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
|
||||
|
@ -128,8 +129,10 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
PhysPt GetDefaultBuffer (void);
|
||||
|
||||
Bit16u numDrives;
|
||||
|
||||
|
||||
typedef struct SDriveInfo {
|
||||
Bit8u drive; // drive letter in dosbox
|
||||
Bit8u physDrive; // drive letter in system
|
||||
|
@ -142,6 +145,7 @@ private:
|
|||
Bit32u volumeSize; // for media change
|
||||
} TDriveInfo;
|
||||
|
||||
PhysPt defaultBuffer;
|
||||
TDriveInfo dinfo[MSCDEX_MAX_DRIVES];
|
||||
CDROM_Interface* cdrom[MSCDEX_MAX_DRIVES];
|
||||
|
||||
|
@ -153,13 +157,18 @@ CMscdex::CMscdex(void)
|
|||
{
|
||||
numDrives = 0;
|
||||
rootDriverHeaderSeg = 0;
|
||||
|
||||
defaultBuffer = 0;
|
||||
|
||||
memset(dinfo,0,sizeof(dinfo));
|
||||
for (Bit32u i=0; i<MSCDEX_MAX_DRIVES; i++) cdrom[i] = 0;
|
||||
};
|
||||
|
||||
CMscdex::~CMscdex(void)
|
||||
{
|
||||
if (defaultBuffer!=0) {
|
||||
DOS_FreeMemory(RealSeg(defaultBuffer));
|
||||
defaultBuffer = 0;
|
||||
}
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) {
|
||||
delete (cdrom)[i];
|
||||
cdrom[i] = 0;
|
||||
|
@ -284,6 +293,16 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
|
|||
return 4;
|
||||
};
|
||||
|
||||
PhysPt CMscdex::GetDefaultBuffer(void)
|
||||
{
|
||||
if (defaultBuffer==0) {
|
||||
Bit16u seg,size = 128;
|
||||
if (!DOS_AllocateMemory(&seg,&size)) E_Exit("MSCDEX: cannot allocate default buffer.");
|
||||
defaultBuffer = PhysMake(seg,0);
|
||||
};
|
||||
return defaultBuffer;
|
||||
};
|
||||
|
||||
void CMscdex::GetDriverInfo (PhysPt data)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) {
|
||||
|
@ -527,6 +546,77 @@ bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data)
|
|||
return ReadSectors(GetSubUnit(drive),false,sector,num,data);
|
||||
};
|
||||
|
||||
bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bitu& error)
|
||||
{
|
||||
char volumeID[6] = {0};
|
||||
char searchName[256];
|
||||
char entryName[256];
|
||||
bool foundComplete = false;
|
||||
bool foundName;
|
||||
char* useName;
|
||||
Bitu entryLength,nameLength;
|
||||
// clear error
|
||||
error = 0;
|
||||
MEM_StrCopy(pathname+1,searchName,mem_readb(pathname));
|
||||
upcase(searchName);
|
||||
char* searchPos = searchName;
|
||||
// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Find : %s",searchName);
|
||||
// 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.");
|
||||
// get directory position
|
||||
Bitu dirEntrySector = mem_readd(defBuffer+156+2);
|
||||
Bits dirSize = mem_readd(defBuffer+156+10);
|
||||
Bitu index;
|
||||
while (dirSize>0) {
|
||||
index = 0;
|
||||
if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false;
|
||||
// Get string part
|
||||
foundName = false;
|
||||
useName = searchPos;
|
||||
searchPos = strchr(searchPos,'\\');
|
||||
if (searchPos) { *searchPos = 0; searchPos++; }
|
||||
else foundComplete = true;
|
||||
|
||||
do {
|
||||
entryLength = mem_readb(defBuffer+index);
|
||||
if (entryLength==0) break;
|
||||
nameLength = mem_readb(defBuffer+index+32);
|
||||
MEM_StrCopy(defBuffer+index+33,entryName,nameLength);
|
||||
if (strcmp(entryName,useName)==0) {
|
||||
// LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName);
|
||||
foundName = true;
|
||||
break;
|
||||
}
|
||||
index += entryLength;
|
||||
} while (index+33<=2048);
|
||||
|
||||
if (foundName) {
|
||||
// TO DO : name gefunden, Daten in den Buffer kopieren
|
||||
if (foundComplete) {
|
||||
if (copyFlag) E_Exit("MSCDEX: GetDirEntry: Unsupported copyflag");
|
||||
// Direct copy
|
||||
MEM_BlockCopy(buffer,defBuffer+index,entryLength);
|
||||
error = iso ? 1:0;
|
||||
return true;
|
||||
}
|
||||
// directory wechseln
|
||||
dirEntrySector = mem_readd(defBuffer+index+2);
|
||||
dirSize = mem_readd(defBuffer+index+10);
|
||||
} else {
|
||||
// continue search in next sector
|
||||
dirSize -= 2048;
|
||||
dirEntrySector++;
|
||||
}
|
||||
};
|
||||
error = 2; // file not found
|
||||
return false; // not found
|
||||
};
|
||||
|
||||
bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos)
|
||||
{
|
||||
if (subUnit>=numDrives) return false;
|
||||
|
@ -863,6 +953,12 @@ static bool MSCDEX_Handler(void)
|
|||
case 0x150D: /* Get drives */
|
||||
mscdex->GetDrives(data);
|
||||
return true;
|
||||
case 0x150F: { // Get directory entry
|
||||
Bitu error;
|
||||
bool success = mscdex->GetDirectoryEntry(reg_cl,reg_ch&1,data,PhysMake(reg_si,reg_di),error);
|
||||
reg_ax = error;
|
||||
CALLBACK_SCF(!success);
|
||||
}; return true;
|
||||
case 0x1510: /* Device driver request */
|
||||
mscdex->SendDriverRequest(reg_cx,data);
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue