Re-add ISO9660 read support from "TempleOSCD_2017-05-21T03 56 09.ISO".

This commit is contained in:
TomAwezome 2022-04-01 23:55:04 -04:00
parent 6f7288e8ed
commit 75d5ea1ecc
10 changed files with 356 additions and 14 deletions

View file

@ -9,6 +9,7 @@ I64 ClusNumNext(CDrive *drive, I64 c, I64 count=1)
unlock = DriveLock(drive);
switch (drive->fs_type)
{
case FSt_ISO9660:
case FSt_REDSEA:
c += count;
break;
@ -44,6 +45,7 @@ I64 Clus2Blk(CDrive *drive, I64 c)
case FSt_REDSEA:
return c;
case FSt_ISO9660:
case FSt_FAT32:
return drive->data_area + c * drive->spc;
@ -69,6 +71,11 @@ I64 ClusBlkRead(CDrive *drive, U8 *buf, I64 c, I64 blks)
c += blks;
break;
case FSt_ISO9660:
BlkRead(drive, buf, drive->data_area + c * drive->spc, blks);
c += (blks + drive->spc - 1) / drive->spc;
break;
case FSt_FAT32:
while (blks && 0 < c < 0x0FFFFFF8)
{

View file

@ -68,7 +68,9 @@ Bool Cd(U8 *dirname=NULL, Bool make_dirs=FALSE)
case FSt_REDSEA:
res = RedSeaCd(buf, cur_dir_clus);
break;
case FSt_ISO9660:
res = ISOCd(buf,cur_dir_clus);
break;
case FSt_FAT32:
res = FAT32Cd(buf, cur_dir_clus);
break;

View file

@ -302,6 +302,7 @@ Bool Drive(U8 drv_let=0)
switch (drive->fs_type)
{
case FSt_REDSEA:
case FSt_ISO9660:
case FSt_FAT32:
return TRUE;

View file

@ -28,6 +28,10 @@ U8 *FileRead(U8 *filename, I64 *_size=NULL, I64 *_attr=NULL)
res = FAT32FileRead(dirc->drive, Fs->cur_dir, dirc->mask, &size, &attr);
break;
case FSt_ISO9660:
res = ISOFileRead(dirc->drive, Fs->cur_dir, dirc->mask, &size, &attr);
break;
default:
PrintErr("File System Not Supported\n");
}
@ -52,6 +56,10 @@ U8 *FileRead(U8 *filename, I64 *_size=NULL, I64 *_attr=NULL)
res = FAT32FileRead(dirc->drive, Fs->cur_dir, dirc->mask, &size, &attr);
break;
case FSt_ISO9660:
res = ISOFileRead(dirc->drive, Fs->cur_dir, dirc->mask, &size, &attr);
break;
default:
PrintErr("File System Not Supported\n");
}

View file

@ -14,6 +14,10 @@ CDirEntry *FilesFind2(U8 *files_find_mask, I64 fuf_flags)
res = FAT32FilesFind(files_find_mask, fuf_flags);
break;
case FSt_ISO9660:
res = ISOFilesFind(files_find_mask, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
res = NULL;
@ -89,6 +93,10 @@ Bool FileFind(U8 *filename, CDirEntry *_de=NULL, I64 fuf_flags=0)
res = FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
case FSt_ISO9660:
res = ISOFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
}
@ -120,6 +128,10 @@ Bool FileFind(U8 *filename, CDirEntry *_de=NULL, I64 fuf_flags=0)
res = FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
case FSt_ISO9660:
res = ISOFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
}

View file

@ -35,6 +35,10 @@ I64 Name2DirClus(CDrive *drive, U8 *dirname)
cont = FAT32FileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
case FSt_ISO9660:
cont = ISOFileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
default:
throw('Drive');
}
@ -86,6 +90,10 @@ I64 Name2ParentDirClus(CDrive *drive, U8 *dirname)
cont = FAT32FileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
case FSt_ISO9660:
cont = ISOFileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
default:
throw('Drive');
}

276
src/Kernel/BlkDev/FileSysISO.ZC Executable file
View file

@ -0,0 +1,276 @@
U0 Date2ISO(CISODate *dst, CDate cdt)
{
CDateStruct ds;
Date2Struct(&ds, cdt);
dst->year = ds.year - ISO_BASE_YEAR;
dst->mon = ds.mon;
dst->day = ds.day_of_mon;
dst->hour = ds.hour;
dst->min = ds.min;
dst->sec = ds.sec;
dst->sec100 = ds.sec100;
}
CDate ISODateStruct2CDate(CISODate *dt)
{
CDateStruct ds;
MemSet(&ds, 0, sizeof(CDateStruct));
ds.day_of_mon = dt->day;
ds.mon = dt->mon;
ds.year = dt->year + ISO_BASE_YEAR;
ds.sec100 = dt->sec100;
ds.sec = dt->sec;
ds.min = dt->min;
ds.hour = dt->hour;
return Struct2Date(&ds);
}
Bool ISOFromName(U8 *dst, U8 *src)
{
I64 i, j, n;
MemSet(dst, 0, CDIR_FILENAME_LEN);
n = *src++;
if (n == 1 && ! *src)
{
*dst = '.';
}
else if (n == 1 && *src == 1)
{
*dst = '.';
dst[1] = '.';
}
else
{
n >>= 1;
j = 0;
for (i = 0; i < n; i++)
{
src++;
if (*src == ';')
break;
if (Bt(char_bmp_filename, *src))
{
if (j >= CDIR_FILENAME_LEN - 1)
return FALSE;
dst[j++] = *src++;
}
else
return FALSE;
}
}
return FileNameCheck(dst);
}
Bool ISOCDirFill(CDirEntry *tmpde, CISODirEntry *de)
{
Bool res;
MemSet(tmpde, 0, sizeof(CDirEntry));
res = ISOFromName(tmpde->name, &de->name_len);
tmpde->clus = de->loc.little;
tmpde->size = de->size.little;
tmpde->attr = FileAttr(tmpde->name);
if (de->flags &ISO_ATTR_DIR)
tmpde->attr |= RS_ATTR_DIR;
tmpde->datetime = ISODateStruct2CDate(&de->date);
return res;
}
Bool ISOFileFind(CDrive *drive, I64 cur_dir_clus, U8 *name, CDirEntry *_res, I64 fuf_flags = 0)
{
//$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$
CISODirEntry *isoptr, *buf;
U8 dname[CDIR_FILENAME_LEN];
Bool res = FALSE, unlock;
I64 i;
if (fuf_flags &~FUG_FILE_FIND)
throw ('FUF');
DriveCheck(drive);
if (drive->fs_type != FSt_ISO9660)
PrintErr("Not ISO9660 Drive\n");
else
try
{
unlock = DriveLock(drive);
isoptr = MAlloc(drive->spc << BLK_SIZE_BITS);
ClusRead(drive, isoptr, cur_dir_clus, 1);
if (isoptr->name_len == 1 && !isoptr->name)
{
//curdir
i = (isoptr->size.little + drive->spc << BLK_SIZE_BITS - 1) / drive->spc << BLK_SIZE_BITS;
buf = MAlloc(drive->spc << BLK_SIZE_BITS * i);
ClusRead(drive, buf, cur_dir_clus, i);
Free(isoptr);
}
else
{
buf = isoptr;
i = 1;
}
i *= drive->spc << BLK_SIZE_BITS;
isoptr = buf;
while (i > 0)
{
if (!isoptr->len)
{
isoptr(U8*)++;
i--;
}
else
{
ISOFromName(dname, &isoptr->name_len);
if (*dname)
{
if (!StrCompare(name, dname))
{
res = ISOCDirFill(_res, isoptr);
if (res &&
!(fuf_flags & FUF_JUST_DIRS && !(_res->attr & RS_ATTR_DIR)) &&
!(fuf_flags & FUF_JUST_FILES && _res->attr & RS_ATTR_DIR))
goto iff_done;
else
res = FALSE;
}
}
i -= isoptr->len;
isoptr(U8*) += isoptr->len;
}
}
iff_done:
Free(buf);
if (unlock)
DriveUnlock(drive);
}
catch
if (unlock)
DriveUnlock(drive);
return res;
}
U8 *ISOFileRead(CDrive *drive, U8 *cur_dir, U8 *filename, I64 *_size, I64 *_attr)
{
U8 *buf = NULL;
CDirEntry de;
I64 c, blk_cnt, cur_dir_clus;
DriveCheck(drive);
*_size = 0;
*_attr = 0;
if (drive->fs_type != FSt_ISO9660)
PrintErr("Not ISO9660 Drive\n");
else
try
{
DriveLock(drive);
cur_dir_clus = Name2DirClus(drive, cur_dir);
if (ISOFileFind(drive, cur_dir_clus, filename, &de, FUF_JUST_FILES))
{
blk_cnt = (de.size + BLK_SIZE - 1) >> BLK_SIZE_BITS;
buf = MAlloc(blk_cnt << BLK_SIZE_BITS + 1);
c = de.clus;
c = ClusBlkRead(drive, buf, c, blk_cnt);
buf[de.size] = 0; //Terminate *_size = de.size;
*_attr = FileAttr(de.name, de.attr);
}
DriveUnlock(drive);
}
catch
DriveUnlock(drive);
return buf;
}
Bool ISOCd(U8 *name, I64 cur_dir_clus)
{
CDirEntry de;
if (Fs->cur_dv->fs_type != FSt_ISO9660)
PrintErr("Not ISO9660 Drive\n");
else if (ISOFileFind(Fs->cur_dv, cur_dir_clus, name, &de, FUF_JUST_DIRS))
return TRUE;
else
PrintErr("File not found: \"%s\".\n", name);
return FALSE;
}
CDirEntry *ISOFilesFind(U8 *files_find_mask, I64 fuf_flags, CDirEntry *parent = NULL)
{
CDrive *drive = Fs->cur_dv;
CISODirEntry *buf, *buf2, *isoptr;
I64 i, cur_dir_clus = Name2DirClus(drive, Fs->cur_dir);
CDirEntry *res = NULL, *tmpde;
if (fuf_flags &~FUG_FILES_FIND)
throw ('FUF');
isoptr = MAlloc(drive->spc << BLK_SIZE_BITS);
ClusRead(drive, isoptr, cur_dir_clus, 1);
if (isoptr->name_len == 1 && !isoptr->name)
{
//curdir
i = (isoptr->size.little + drive->spc << BLK_SIZE_BITS - 1) / drive->spc << BLK_SIZE_BITS;
buf = MAlloc(drive->spc << BLK_SIZE_BITS *i);
ClusRead(drive, buf, cur_dir_clus, i);
Free(isoptr);
}
else
{
buf = isoptr;
i = 1;
}
buf2 = buf;
i *= drive->spc << BLK_SIZE_BITS;
while (i > 0)
{
if (!buf->len)
{
buf(U8*) ++;
i--;
}
else
{
tmpde = MAlloc(sizeof(CDirEntry));
if (ISOCDirFill(tmpde, buf))
{
tmpde->parent = parent;
if (Bt(&fuf_flags, FUf_RECURSE) && tmpde->attr & RS_ATTR_DIR && *tmpde->name != '.')
{
tmpde->next = res;
res = tmpde;
tmpde->full_name = DirNameAbs(tmpde->name);
if (Cd(tmpde->name))
{
tmpde->sub = ISOFilesFind(files_find_mask, fuf_flags, tmpde);
Cd("..");
}
}
else
{
tmpde->full_name = FileNameAbs(tmpde->name);
if ((tmpde->attr &RS_ATTR_DIR || !Bt(&fuf_flags, FUf_JUST_DIRS)) &&
!(Bt(&fuf_flags, FUf_RECURSE) && *tmpde->name == '.' && tmpde->attr & RS_ATTR_DIR) &&
FilesFindMatch(tmpde->full_name, files_find_mask, fuf_flags))
{
tmpde->next = res;
res = tmpde;
}
else
DirEntryDel(tmpde);
}
}
else
DirEntryDel(tmpde);
i -= buf->len;
buf(U8*) += buf->len;
}
}
Free(buf2);
return res;
}

View file

@ -10,6 +10,7 @@
#include "DiskStrB"
#include "DiskAddDev"
#include "DiskDirA"
#include "FileSysISO"
#include "FileSysRedSea"
#include "FileSysFAT"
#include "DiskDirContext"

View file

@ -80,7 +80,7 @@ extern I64 StrNGet(U8 *buf, I64 size, Bool allow_ext=TRUE);
extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL, CTask *task=NULL, CBlkPool *bp);
extern Bool ISOInit(CDrive *drive, I64 blk);
extern Bool ISOFileFind(CDrive *drive, I64 cur_dir_clus, U8 *name, CDirEntry *_res, I64 fuf_flags=0);
extern Bool IsDebugMode();
extern Bool IsDir(U8 *dir_name);
extern Bool IsRaw();

View file

@ -3144,6 +3144,30 @@ class CPalindromeU32
U32 little, big;
};
class CISODate
{
U8 year, mon, day, hour, min, sec, sec100;
};
class CISODirEntry
{
U8 len, ext_attr_len;
CPalindromeU32 loc;
CPalindromeU32 size;
CISODate date;
U8 flags, file_unit_size, interleave;
CPalindromeU16 vol_seq_num;
U8 name_len, name;
};
class CISOPathEntry
{
U8 name_len, zero;
U32 blk;
U16 parent_entry_num,
name[1]; //Aligned to U16 boundaries
};
//ISO9660
#define ISOT_BOOT_RECORD 0
#define ISOT_PRI_VOL_DESC 1
@ -3151,27 +3175,27 @@ class CPalindromeU32
#define ISOT_VOL_DRIVE_DESC 3
#define ISOT_TERMINATOR 255
class CISODirEntry
{
U8 pad[2];
CPalindromeU32 loc;
U8 pad[24];
};
class CISOPriDesc
{
U8 type,
id[5],
version,
pad[73];
unused1,
system_id[32],
vol_id[32],
unused2[8];
CPalindromeU32 vol_space_size;
U8 pad[32];
U8 unused3[32];
CPalindromeU16 vol_set_size;
CPalindromeU16 vol_seq_num;
CPalindromeU16 log_block_size;
U8 pad[24];
CPalindromeU32 path_table_size;
U32 type_l_path_table,
opt_type_l_path_table,
type_m_path_table,
opt_type_m_path_table;
CISODirEntry root_dir_record;
U8 pad[128],
U8 vol_set_id[128],
publisher_id[128],
preparer_id[128],
pad[307],
@ -3179,6 +3203,9 @@ class CISOPriDesc
pad[1166];
};
#define ISO_BASE_YEAR 1900
#define ISO_ATTR_DIR 2
//Red Sea Attributes
//See $LK,"ST_FILE_ATTRS",A="MN:ST_FILE_ATTRS"$
#define RS_ATTR_READ_ONLY 0x01 //R
@ -3343,7 +3370,7 @@ public class CBlkDev
#define FSt_NULL 0
#define FSt_REDSEA 1 //Supported
#define FSt_FAT32 2 //Supported except for short names, to some degree
#define FSt_ISO9660 3 //Not Supported
#define FSt_ISO9660 3 //Supported (CD/DVD)
#define FSt_NTFS 4 //Not Supported
#define FSt_LINUX 5 //Not Supported
#define FSt_SWAP 6 //Not Supported