Totally unrelated thing to dots in the path .
Some PSX discs have corrupted directory entries and that prevents DIC from proceeding further to the dump.
It just hangs on "Reading DirectoryRecord". I recently got "All Star Racing 2 (Europe)" disc and that was problematic to dump.
Based on my findings here (I wrote a tool) here is the list of PSX titles which have corrupted directory entries:
Aitakute... - Your Smiles in My Heart (Japan) (Disc 1) (Track 1).bin
Aitakute... - Your Smiles in My Heart (Japan) (Disc 2) (Track 1).bin
Aitakute... - Your Smiles in My Heart (Japan) (Disc 3) (Track 1).bin
Aitakute... - Your Smiles in My Heart (Japan) (Disc 4) (Track 1).bin
Aitakute... - Your Smiles in My Heart - Oroshitate no Diary - Introduction Disc (Japan) (Track 1).bin
All Star Racing 2 (Europe) (Track 1).bin
All Star Racing 2 (USA) (Track 1).bin
Formula GP (Europe) (Track 1).bin
MLB 2005 (USA).bin
Strike Force Hydra (Europe) (Track 1).bin
Tokimeki Memorial - Forever with You (Japan) (PlayStation the Best) (Track 1).bin
Tokimeki Memorial - Forever with You (Japan) (Rev 2) (Track 1).bin
Tokimeki Memorial - Forever with You (Japan) (Rev 4) (Track 1).bin
Truck Racing (Europe) (Track 1).bin
A tricky but IMO a good way to validate directory entry is to compare little endian offset and data_length to it's big endian counterpart.
// iso9660 definitions
struct uint64_lsb_msb
{
uint32_t lsb;
uint32_t msb;
};
struct DirectoryRecord
{
uint8_t length;
uint8_t xa_length;
uint64_lsb_msb offset;
uint64_lsb_msb data_length;
struct RecordingDateTime
{
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t gmt_offset;
} recording_date_time;
uint8_t file_flags;
uint8_t file_unit_size;
uint8_t interleave_gap_size;
uint32_t volume_sequence_number;
uint8_t file_identifier_length;
};
// check
DirectoryRecord &dr = *(iso9660::DirectoryRecord *)&buffer[i];
if(dr.offset.lsb != endian_swap(dr.offset.msb) || dr.data_length.lsb != endian_swap(dr.data_length.msb))
// invalid record, skip the sector
;
How I did it in your codebase execScsiCmdforFileSystem.cpp snippet:
BOOL DirectoryRecordValid(
LPBYTE lpDirRec
) {
// check if stored LSB data is the same as MSB data
return lpDirRec[ 2] == lpDirRec[ 9] && lpDirRec[ 3] == lpDirRec[ 8] && lpDirRec[ 4] == lpDirRec[ 7] && lpDirRec[ 5] == lpDirRec[ 6] && // offset
lpDirRec[10] == lpDirRec[17] && lpDirRec[11] == lpDirRec[16] && lpDirRec[12] == lpDirRec[15] && lpDirRec[13] == lpDirRec[14]; // data length
}
BOOL ReadDirectoryRecordDetail(
PEXEC_TYPE pExecType,
PEXT_ARG pExtArg,
PDEVICE pDevice,
PDISC pDisc,
LPBYTE pCdb,
INT nLBA,
LPBYTE lpBuf,
LPBYTE bufDec,
BYTE byTransferLen,
INT nDirPosNum,
UINT uiLogicalBlkCoef,
INT nOffset,
PDIRECTORY_RECORD pDirRec
) {
if (!ExecReadDisc(pExecType, pExtArg, pDevice, pDisc
, pCdb, nLBA + nOffset, lpBuf, bufDec, byTransferLen, _T(__FUNCTION__), __LINE__)) {
return FALSE;
}
BYTE byRoop = byTransferLen;
if (*pExecType == gd) {
byRoop = (BYTE)(byRoop - 1);
}
for (BYTE i = 0; i < byRoop; i++) {
OutputCDMain(fileMainInfo, lpBuf + DISC_RAW_READ_SIZE * i, nLBA + i, DISC_RAW_READ_SIZE);
}
UINT uiOfs = 0;
for (INT nSectorNum = 0; nSectorNum < byRoop;) {
if (*(lpBuf + uiOfs) == 0) {
break;
}
OutputVolDescLogA(
OUTPUT_DHYPHEN_PLUS_STR_WITH_LBA_F(Directory Record), nLBA + nSectorNum, nLBA + nSectorNum);
for (;;) {
CHAR szCurDirName[MAX_FNAME_FOR_VOLUME] = {};
LPBYTE lpDirRec = lpBuf + uiOfs;
if (lpDirRec[0] >= MIN_LEN_DR) {
if (!DirectoryRecordValid(lpDirRec) || (lpDirRec[0] == MIN_LEN_DR && uiOfs > 0 && uiOfs % DISC_RAW_READ_SIZE == 0)) {
// SimCity 3000 (USA)
OutputVolDescLogA(
"Direcory record size of the %d sector maybe incorrect. Skip the reading of this sector\n", nLBA);
nSectorNum++;
break;
}
I didn't want to mix it in with the dot fixes before you approve the pull request so here it is if you think it's useful.