diff --git a/src/Doc/Credits.DD b/src/Doc/Credits.DD index 6351f9ce..efcf085e 100755 --- a/src/Doc/Credits.DD +++ b/src/Doc/Credits.DD @@ -1,6 +1,6 @@ $WW,1$$FG,5$$TX+CX,"Credits"$$FG$ -$FG,2$Terry A. Davis$FG$ wrote all of TempleOS over a span of $FG,2$$TX,"15.0",D="DD_TEMPLEOS_AGE"$$FG$ years (full-time). ZealOS, written over a span of $FG,2$$TX,"2.3",D="DD_ZEALOS_AGE"$$FG$ years, is a fork of TempleOS. It can run on some bare metal 64-bit PC's from about 2007-2019 with no layering, libraries, tools, modules or anything from other sources. Otherwise, you run it in a virtual machine, like $FG,2$VMware$FG$, $FG,2$QEMU$FG$ or $FG,2$VirtualBox$FG$. It is independent and stands alone. 100% of the src code is including on all distro's, from the kernel to the compiler to the boot loaders! It is public domain, not GPL. +$FG,2$Terry A. Davis$FG$ wrote all of TempleOS over a span of $FG,2$$TX,"15.0",D="DD_TEMPLEOS_AGE"$$FG$ years (full-time). ZealOS, written over a span of $FG,2$$TX,"2.6",D="DD_ZEALOS_AGE"$$FG$ years, is a fork of TempleOS. It can run on some bare metal 64-bit PC's from about 2007-2019 with no layering, libraries, tools, modules or anything from other sources. Otherwise, you run it in a virtual machine, like $FG,2$VMware$FG$, $FG,2$QEMU$FG$ or $FG,2$VirtualBox$FG$. It is independent and stands alone. 100% of the src code is including on all distro's, from the kernel to the compiler to the boot loaders! It is public domain, not GPL. *) $LK,"ATA Reg and Cmd Definitions",A="MN:ATA_NOP"$ are originally from Linux. Later, Terry got the spec. @@ -18,6 +18,8 @@ $FG,2$Terry A. Davis$FG$ wrote all of TempleOS over a span of $FG,2$$TX,"15.0",D *) Thanks to whoever wrote this $FG,4$$TX,"CppHtml.ZC",HTML="http://web.archive.org/web/20100325153025/http://home.scarlet.be/zoetrope/cpphtml.htm"$$FG$. Terry was a novice on web stuff and you helped him with html. See $LK,"::/Demo/ToHtmlToTXTDemo/ToHtml.ZC"$. +*) Terry used the $FG,4$$TX,"ISO9660",HTML="http://users.telenet.be/it3.consultants.bvba/handouts/ISO9960.html"$$FG$ spec to help him understand the ISO9660 file system format. + *) Terry looked at bootable CD boot sectors, but didn't learn anything, finding it easier to make his own. *) Terry thought he got his original PC speaker code from $FG,2$Borland C$FG$. diff --git a/src/Doc/Features.DD b/src/Doc/Features.DD index 02d375c9..20657e98 100755 --- a/src/Doc/Features.DD +++ b/src/Doc/Features.DD @@ -16,9 +16,9 @@ * Keyboard & Mouse support. -* AHCI ATA Hard drives, support for $FG,2$FAT32$FG$ and $LK,"RedSea",A="FI:::/Doc/RedSea.DD"$ file systems. +* AHCI ATA hard drives, support for $FG,2$FAT32$FG$ and $LK,"RedSea",A="FI:::/Doc/RedSea.DD"$ file systems. -* AHCI ATAPI $FG,2$CD/DVD$FG$ support with $FG,2$RedSea$FG$ file system. Can make bootable ISO files so you can roll-your-own distro's. +* AHCI ATAPI $FG,2$CD/DVD$FG$ drives, support for $FG,2$ISO9660$FG$ and $LK,"RedSea",A="FI:::/Doc/RedSea.DD"$ file systems. Can make bootable ISO files so you can roll-your-own distro's. * $LK,"Partitioning",A="MN:DiskPart"$ tool, installer, $FG,2$boot loaders$FG$ for CD/DVD and hard disk. diff --git a/src/Doc/FileMgr.DD b/src/Doc/FileMgr.DD index 989c33c7..73e1d47d 100755 --- a/src/Doc/FileMgr.DD +++ b/src/Doc/FileMgr.DD @@ -51,6 +51,9 @@ $ID,-2$ $FG,2$'m'$FG$ $ID,2$Make CD/DVD ISO.C file. This creates a $LK,"RedSea",A="FI:::/Doc/RedSea.DD"$ ISO file image of the dir the cursor is on. The name of the ISO file is $FG,2$$TX,"\"::/Tmp/CDDVD.ISO.C\"",D="DEFAULT_ISO_C_FILENAME"$$FG$ $LK,"blkdev.default_iso_c_filename",A="MN:CBlkDevGlobals"$ and can be redefined in your start-up scripts. You may wish to place it on a different drive. $ID,-2$ +$FG,2$'M'$FG$ +$ID,2$Make CD/DVD ISO file. This creates a ISO9660 file image of the dir the cursor is on. The name of the ISO file is$FG,2$$TX,"",D="DFT_ISO_FILENAME"$$FG$ $LK,"blkdev.default_iso_filename",A="MN:CBlkDevGlobals"$ and can be redefined in your start-up scripts. You may wish to place it on a different drive. +$ID,-2$ $FG,2$'B'$FG$ $ID,2$Burn CD/DVD ISO file. This burns a CD/DVD using the image file, $FG,2$$TX,"\"::/Tmp/CDDVD.ISO\"",D="DEFAULT_ISO_FILENAME"$$FG$ $LK,"blkdev.default_iso_filename",A="MN:CBlkDevGlobals"$ to the drive the cursor is on. $ID,-2$ diff --git a/src/Doc/FileMgrPullDown.DD b/src/Doc/FileMgrPullDown.DD index cf6f581c..b55afe51 100755 --- a/src/Doc/FileMgrPullDown.DD +++ b/src/Doc/FileMgrPullDown.DD @@ -21,6 +21,7 @@ CDDVD DiskChange(,'c'); MountISOC(,'i'); MakeRedSeaISOC(,'m'); + MakeISO9660ISO(,'M'); BurnISOFile(,'B'); } diff --git a/src/Doc/Glossary.DD b/src/Doc/Glossary.DD index f0c5e7be..ef4bfde6 100755 --- a/src/Doc/Glossary.DD +++ b/src/Doc/Glossary.DD @@ -218,7 +218,7 @@ $FG,5$*.ZXE;*.ZXE$FG$ $FG,5$*.DATA$FG$ Data files $FG,5$*.ISO;*.ISO.C$FG$ - CD/DVD image file. + CD/DVD image file. $LK,"RedSea",A="FI:::/Doc/RedSea.DD"$ or ISO9660. $FG,5$*.IN$FG$ $FG,2$InFile$FG$ Basically a ZealC program whose stdout goes to the input of a task when $LK,"InFile",A="MN:InFile"$() is called. $FG,5$*.GR$FG$ diff --git a/src/Doc/HelpIndex.DD b/src/Doc/HelpIndex.DD index b1483a4a..c34c06ce 100755 Binary files a/src/Doc/HelpIndex.DD and b/src/Doc/HelpIndex.DD differ diff --git a/src/Doc/Requirements.DD b/src/Doc/Requirements.DD index 9ab7adbc..cee25054 100755 --- a/src/Doc/Requirements.DD +++ b/src/Doc/Requirements.DD @@ -14,7 +14,7 @@ $FG,5$Supported Hardware$FG$ * Internal PC Speakers. -* CD/DVD-ROMs (not SCSI) but only RedSea file system. +* CD/DVD-ROMs (not SCSI), RedSea or ISO9660 file system. * SATA hard drives. (SATA, mSATA, m.2) diff --git a/src/Doc/StandBy.DD b/src/Doc/StandBy.DD index 4ed2e933..40328cf8 100755 --- a/src/Doc/StandBy.DD +++ b/src/Doc/StandBy.DD @@ -22,4 +22,4 @@ $FG,2$ $FG$ God Word $FG,2$ $FG$ God Passage $FG,2$ $FG$ God Song $FG,2$$FG$ Close AC -$FG,2$ $FG$ Open AC \ No newline at end of file +$FG,2$ $FG$ Open AC diff --git a/src/Kernel/BlkDev/DiskClus.ZC b/src/Kernel/BlkDev/DiskClus.ZC index a8243988..d24b9c9f 100755 --- a/src/Kernel/BlkDev/DiskClus.ZC +++ b/src/Kernel/BlkDev/DiskClus.ZC @@ -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) { @@ -134,6 +141,10 @@ I64 ClusBlkWrite(CDrive *drive, U8 *buf, I64 c, I64 blks) } break; + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + throw('Drive'); + default: throw('Drive'); } @@ -171,6 +182,11 @@ I64 ClusAlloc(CDrive *drive, I64 c=0, I64 count=1, Bool contiguous=FALSE) else return FAT32AllocClus(drive, c, count); + + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + throw('Drive'); + default: throw('Drive'); } diff --git a/src/Kernel/BlkDev/DiskCopy.ZC b/src/Kernel/BlkDev/DiskCopy.ZC index 52aa6b7a..87ce38f6 100755 --- a/src/Kernel/BlkDev/DiskCopy.ZC +++ b/src/Kernel/BlkDev/DiskCopy.ZC @@ -113,6 +113,10 @@ I64 Del(U8 *files_find_mask, Bool make_mask=FALSE, Bool del_dir=FALSE, Bool prin res = FAT32FilesDel(dirc->drive, Fs->cur_dir, dirc->mask, 0, del_dir, print_message); break; + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + break; + default: PrintErr("File System Not Supported\n"); } diff --git a/src/Kernel/BlkDev/DiskDirA.ZC b/src/Kernel/BlkDev/DiskDirA.ZC index 133750dd..cfaa5ba4 100755 --- a/src/Kernel/BlkDev/DiskDirA.ZC +++ b/src/Kernel/BlkDev/DiskDirA.ZC @@ -8,6 +8,10 @@ Bool DirNew(CDrive *drive, U8 *cur_dir, CDirEntry *tmpde, Bool free_old_chain=TR case FSt_FAT32: return FAT32DirNew(drive, cur_dir, tmpde, free_old_chain); + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + return FALSE; + default: PrintErr("File System Not Supported\n"); return FALSE; diff --git a/src/Kernel/BlkDev/DiskDirB.ZC b/src/Kernel/BlkDev/DiskDirB.ZC index 7b05ac7f..96f06abe 100755 --- a/src/Kernel/BlkDev/DiskDirB.ZC +++ b/src/Kernel/BlkDev/DiskDirB.ZC @@ -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; @@ -151,7 +153,7 @@ I64 Dir(U8 *files_find_mask, Bool full) "$$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$$ of %s\n", st; if (full) - "__DATE__ __TIME__ %*ts %*ts\n", csize, "SIZE", c, "BLK"; + "__DATE__ __TIME__ %*ts %*ts\n", csize, "SIZE", c, "CLUS"; else "DATE_ TIME_ %*ts\n", csize, "SIZE"; while (tmpde1) @@ -210,6 +212,10 @@ Bool DirMake(U8 *filename, I64 entry_count=0) res = FAT32MkDir(dirc->drive, Fs->cur_dir, name, entry_count); break; + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + break; + default: PrintErr("File System Not Supported\n"); } diff --git a/src/Kernel/BlkDev/DiskDrive.ZC b/src/Kernel/BlkDev/DiskDrive.ZC index bdaa6cf9..13508206 100755 --- a/src/Kernel/BlkDev/DiskDrive.ZC +++ b/src/Kernel/BlkDev/DiskDrive.ZC @@ -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; diff --git a/src/Kernel/BlkDev/DiskFile.ZC b/src/Kernel/BlkDev/DiskFile.ZC index e9b0d416..107bf131 100755 --- a/src/Kernel/BlkDev/DiskFile.ZC +++ b/src/Kernel/BlkDev/DiskFile.ZC @@ -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"); } @@ -95,6 +103,10 @@ I64 FileWrite(U8 *filename, U8 *fbuf, I64 size, CDate cdt=0, I64 attr=0) c = FAT32FileWrite(dirc->drive, Fs->cur_dir, dirc->mask, fbuf, size, cdt, attr); break; + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + break; + default: PrintErr("File System Not Supported\n"); } diff --git a/src/Kernel/BlkDev/DiskFind.ZC b/src/Kernel/BlkDev/DiskFind.ZC index 8196e723..2178adab 100755 --- a/src/Kernel/BlkDev/DiskFind.ZC +++ b/src/Kernel/BlkDev/DiskFind.ZC @@ -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"); } diff --git a/src/Kernel/BlkDev/DiskFormat.ZC b/src/Kernel/BlkDev/DiskFormat.ZC index 0e1b696b..a66a8614 100755 --- a/src/Kernel/BlkDev/DiskFormat.ZC +++ b/src/Kernel/BlkDev/DiskFormat.ZC @@ -37,6 +37,10 @@ Bool DriveTypeSet(U8 drv_let, I64 type=FSt_REDSEA) mbr.p[i].type = MBR_PT_FAT32a; break; + case FSt_ISO9660: + PrintErr("File System Not Writable\n"); + throw('Drive'); + default: throw('Drive'); } diff --git a/src/Kernel/BlkDev/DiskStrB.ZC b/src/Kernel/BlkDev/DiskStrB.ZC index 02b24624..227bacbe 100755 --- a/src/Kernel/BlkDev/DiskStrB.ZC +++ b/src/Kernel/BlkDev/DiskStrB.ZC @@ -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'); } diff --git a/src/Kernel/BlkDev/FileSysISO.ZC b/src/Kernel/BlkDev/FileSysISO.ZC new file mode 100755 index 00000000..c69b0cbd --- /dev/null +++ b/src/Kernel/BlkDev/FileSysISO.ZC @@ -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; +} diff --git a/src/Kernel/BlkDev/MakeBlkDev.ZC b/src/Kernel/BlkDev/MakeBlkDev.ZC index e86d533f..2482403a 100755 --- a/src/Kernel/BlkDev/MakeBlkDev.ZC +++ b/src/Kernel/BlkDev/MakeBlkDev.ZC @@ -10,6 +10,7 @@ #include "DiskStrB" #include "DiskAddDev" #include "DiskDirA" +#include "FileSysISO" #include "FileSysRedSea" #include "FileSysFAT" #include "DiskDirContext" diff --git a/src/Kernel/KExterns.ZC b/src/Kernel/KExterns.ZC index 6c1aa937..918d887f 100755 --- a/src/Kernel/KExterns.ZC +++ b/src/Kernel/KExterns.ZC @@ -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(); diff --git a/src/Kernel/KernelA.HH b/src/Kernel/KernelA.HH index 595ae1d8..2729c8f3 100755 --- a/src/Kernel/KernelA.HH +++ b/src/Kernel/KernelA.HH @@ -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 diff --git a/src/Kernel/KernelC.HH b/src/Kernel/KernelC.HH index 0236f816..87a6d99e 100755 --- a/src/Kernel/KernelC.HH +++ b/src/Kernel/KernelC.HH @@ -697,6 +697,7 @@ public extern CCountsGlobals counts; #help_index "Time/Date/CDate;Date/CDate" #help_file "::/Doc/TimeDate" public extern U0 Date2Struct(CDateStruct *_ds, CDate cdt); +extern U0 Date2ISO(CISODate *dst, CDate cdt); extern U8 *MPrintDate(CDate cdt); extern U8 *MPrintTime(CDate cdt); public extern CDate Now(); diff --git a/src/System/BlkDev/FileMgr.ZC b/src/System/BlkDev/FileMgr.ZC index 56f5d2fb..b1ad2cb9 100755 --- a/src/System/BlkDev/FileMgr.ZC +++ b/src/System/BlkDev/FileMgr.ZC @@ -464,10 +464,11 @@ U0 FMFormatDrive(CDoc *doc) Free(st); } -U0 FMMakeISO(CDoc *doc) +U0 FMMakeISO(CDoc *doc, I64 type) { CDocEntry *doc_ce = doc->cur_entry; CDirEntry *tmpde; + U8 *st; if (doc_ce->type_u8 == DOCT_TREE || doc_ce->type_u8 == DOCT_MENU_VAL) tmpde = doc_ce->user_data; @@ -480,7 +481,21 @@ U0 FMMakeISO(CDoc *doc) if (tmpde && *tmpde->full_name) { Silent; - RedSeaISO(, tmpde->full_name); + switch (type) + { + case FSt_REDSEA: + RedSeaISO(, tmpde->full_name); + break; + + case FSt_ISO9660: + if (tmpde->full_name[StrLen(tmpde->full_name) - 1] == '/') + st = MStrPrint("%s*", tmpde->full_name); + else + st = MStrPrint("%s/*", tmpde->full_name); + ISO9660ISO(, st); + Free(st); + break; + } Silent(OFF); } } @@ -570,8 +585,9 @@ U0 FMCopy(CDoc *doc) #define FMR_MOUNT_REDSEA_ISO_C 8 #define FMR_UNMOUNT 9 #define FMR_MAKE_REDSEA_ISO_C 10 -#define FMR_BURN_ISO 11 -#define FMR_HELP 12 +#define FMR_MAKE_ISO9660 11 +#define FMR_BURN_ISO 12 +#define FMR_HELP 13 I64 PopUpFMRight(U8 *header=NULL, U8 *footer=NULL) { @@ -592,9 +608,10 @@ I64 PopUpFMRight(U8 *header=NULL, U8 *footer=NULL) "$$CM+LX,1,3 $$$$BT,\"MOUNT ISO.C FILE \",LE=FMR_MOUNT_REDSEA_ISO_C$$" "$$CM+LX,29,0$$$$BT,\"UNMOUNT \",LE=FMR_UNMOUNT$$" "$$CM+LX,1,3 $$$$BT,\"MAKE ISO.C (CD/DVD) FILE\",LE=FMR_MAKE_REDSEA_ISO_C$$" - "$$CM+LX,29,0$$$$BT,\"BURN ISO (CD/DVD) FILE \",LE=FMR_BURN_ISO$$" - "$$CM+LX,1,3 $$$$BT,\"HELP \",LE=FMR_HELP$$" - "$$CM+LX,29,0$$$$BT,\"CANCEL \",LE=DOCM_CANCEL$$\n"); + "$$CM+LX,29,0$$$$BT,\"MAKE ISO (CD/DVD) FILE \",LE=FMR_MAKE_ISO9660$$" + "$$CM+LX,1,3 $$$$BT,\"BURN ISO (CD/DVD) FILE \",LE=FMR_BURN_ISO$$" + "$$CM+LX,29,0$$$$BT,\"HELP \",LE=FMR_HELP$$" + "$$CM+LX,1,3 $$$$BT,\"CANCEL \",LE=DOCM_CANCEL$$\n"); if (footer) DocPrint(doc, "%s", footer); @@ -652,12 +669,16 @@ U0 FMRightClick() Message(MESSAGE_KEY_DOWN, 'm', 0); break; + case FMR_MAKE_ISO9660: + Message(MESSAGE_KEY_DOWN, 'M', 0); + break; + case FMR_BURN_ISO: Message(MESSAGE_KEY_DOWN, 'B', 0); break; case FMR_HELP: - Message(MESSAGE_KEY_DOWN, CH_CTRLM, 0x43200000432); + PopUpEd("::/Doc/FileMgr.DD"); break; } } @@ -841,7 +862,11 @@ public U8 *FileMgr(I64 mode=FM_NORMAL, CTask *mem_task=NULL) break; case 'm': - FMMakeISO(doc); + FMMakeISO(doc, FSt_REDSEA); + break; + + case 'M': + FMMakeISO(doc, FSt_ISO9660); break; case 'B': diff --git a/src/System/Boot/BootDVDIns.ZC b/src/System/Boot/BootDVDIns.ZC index 48f18e0d..89a0ee72 100755 --- a/src/System/Boot/BootDVDIns.ZC +++ b/src/System/Boot/BootDVDIns.ZC @@ -3,6 +3,7 @@ #include "BootDVD" #include "DiskISORedSea" +#include "DiskISO9660" #help_index "Install" diff --git a/src/System/Boot/DiskISO9660.ZC b/src/System/Boot/DiskISO9660.ZC new file mode 100755 index 00000000..d47b4cc4 --- /dev/null +++ b/src/System/Boot/DiskISO9660.ZC @@ -0,0 +1,540 @@ +#help_index "File/CD DVD" + +class CCDVDUserData //Create DVD +{ + I64 loc, path_entry_num, short_dir_blks, long_dir_blks; +}; + +I64 DVDFileCreate2(CFile *out_file, CDirEntry *tmpde, CISODirEntry *tmpi, + CISODirEntry *tmpi2, I64 *_cur_blk, CDirEntry *parent, Bool write, + U8 *stage2_filename, I64 *_stage2_blk) +{ + CCDVDUserData *tmpc; + CDirEntry *tmpde1, *tmpde2; + CFile *in_file; + U8 *buf = MAlloc(DVD_BLK_SIZE), *ptr1, *ptr2; + CISODirEntry *dir_blk_buf = CAlloc(DVD_BLK_SIZE * 128), + *de = dir_blk_buf, *de1, + *dir_blk_buf2 = CAlloc(DVD_BLK_SIZE * 128), + *de2 = dir_blk_buf2, *de12; + I64 i, n; + + tmpc = parent->user_data; + + de->len = sizeof(CISODirEntry) - 1; + de->ext_attr_len = 0; + FillU16Palindrome(&de->vol_seq_num, 1); + Date2ISO(&de->date, tmpde->datetime); + de->flags = ISO_ATTR_DIR; + de->name_len = 1; + de->name = 0; + de->len += de->name_len; + de(U8 *) += de->len; + + de->len = sizeof(CISODirEntry) - 1; + de->ext_attr_len = 0; + FillU32Palindrome(&de->loc, tmpc->loc); + FillU32Palindrome(&de->size, tmpc->short_dir_blks * DVD_BLK_SIZE); + FillU16Palindrome(&de->vol_seq_num, 1); + Date2ISO(&de->date, parent->datetime); + de->flags = ISO_ATTR_DIR; + de->name_len = 1; + de->name = 1; + de->len += de->name_len; + de(U8 *) += de->len; + + de2->len = sizeof(CISODirEntry) - 1; + de2->ext_attr_len = 0; + FillU16Palindrome(&de2->vol_seq_num, 1); + Date2ISO(&de2->date, tmpde->datetime); + de2->flags = ISO_ATTR_DIR; + de2->name_len = 1; + de2->name = 0; + de2->len += de2->name_len; + de2(U8 *) += de2->len; + + de2->len = sizeof(CISODirEntry) - 1; + de2->ext_attr_len = 0; + FillU32Palindrome(&de2->loc, tmpc->loc + tmpc->short_dir_blks); + FillU32Palindrome(&de2->size, tmpc->long_dir_blks * DVD_BLK_SIZE); + FillU16Palindrome(&de2->vol_seq_num, 1); + Date2ISO(&de2->date, parent->datetime); + de2->flags = ISO_ATTR_DIR; + de2->name_len = 1; + de2->name = 1; + de2->len += de2->name_len; + de2(U8 *) += de2->len; + + tmpde1 = tmpde->sub; + while (tmpde1) + { + tmpde2 = tmpde1->next; + if (!write) + tmpde1->user_data = CAlloc(sizeof(CCDVDUserData)); + de1 = de; + de12 = de2; + if (tmpde1->attr & RS_ATTR_DIR) + { + n = DVDFileCreate2(out_file, tmpde1, de, de2, _cur_blk, + tmpde, write, stage2_filename, _stage2_blk); + de(U8 *) += sizeof(CISODirEntry) - 1 + n; + de2(U8 *) += sizeof(CISODirEntry) - 1 + n << 1; + } + else + { + tmpc = tmpde1->user_data; + de->len = sizeof(CISODirEntry) - 1; + de->ext_attr_len = 0; + FillU32Palindrome(&de->loc, *_cur_blk); + tmpc->loc = *_cur_blk; + if (write) + { + if (stage2_filename && !StrCompare(tmpde1->full_name, stage2_filename)) + { + "$$RED$$!!! Boot Stage 2 !!!$$FG$$\n"; + if (_stage2_blk) + *_stage2_blk = *_cur_blk; + } + "%X:%s\n", *_cur_blk, tmpde1->full_name; + } + FillU32Palindrome(&de->size, tmpde1->size); + FillU16Palindrome(&de->vol_seq_num, 1); + Date2ISO(&de->date, tmpde1->datetime); + de->flags = 0; + de->name_len = StrLen(tmpde1->name); + StrCopy(&de->name, tmpde1->name); + de->len = de->len + de->name_len; + de(U8 *) += de->len; + + de2->len = sizeof(CISODirEntry) - 1; + de2->ext_attr_len = 0; + FillU32Palindrome(&de2->loc, *_cur_blk); + FillU32Palindrome(&de2->size, tmpde1->size); + FillU16Palindrome(&de2->vol_seq_num, 1); + Date2ISO(&de2->date, tmpde1->datetime); + de2->flags = 0; + de2->name_len = StrLen(tmpde1->name) << 1; + ptr1 = &de2->name; + ptr2 = &tmpde1->name; + for (i = 0; i < de2->name_len; i = i + 2) + { + ptr1++; + *ptr1++ = *ptr2++; + } + de2->len += de2->name_len; + de2(U8 *) += de2->len; + + in_file = FOpen(tmpde1->full_name, "r"); + for (i = 0; i < (FSize(in_file) + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; i++) + { + n = 4; + if ((i + 1) << 2 > (FSize(in_file) + BLK_SIZE - 1) >> BLK_SIZE_BITS) + { + n = (FSize(in_file) + BLK_SIZE - 1) >> BLK_SIZE_BITS & 3; + MemSet(buf, 0, DVD_BLK_SIZE); + } + if (write) + { + FBlkRead(in_file, buf, i << 2, n); + FBlkWrite(out_file, buf, *_cur_blk << 2, n); + } + *_cur_blk += 1; + } + FClose(in_file); + } + if ((de1(U8 *) - dir_blk_buf(U8 *)) / DVD_BLK_SIZE != + (de(U8 *) - dir_blk_buf(U8 *)) / DVD_BLK_SIZE) + { + i = de1->len; + MemCopy(buf, de1, i); + MemSet(de1, 0, i); + de = dir_blk_buf(U8 *) + (de(U8 *) - dir_blk_buf(U8 *)) / DVD_BLK_SIZE * DVD_BLK_SIZE; + MemCopy(de, buf, i); + de(U8 *) += i; + } + if ((de12(U8 *) - dir_blk_buf2(U8 *)) / DVD_BLK_SIZE != + (de2(U8 *) - dir_blk_buf2(U8 *)) / DVD_BLK_SIZE) + { + i = de12->len; + MemCopy(buf, de12, i); + MemSet(de12, 0, i); + de2(U8 *) = dir_blk_buf2(U8 *) + (de2(U8 *) - + dir_blk_buf2(U8 *)) / DVD_BLK_SIZE * DVD_BLK_SIZE; + MemCopy(de2, buf, i); + de2(U8 *) += i; + } + tmpde1 = tmpde2; + } + + tmpc = tmpde->user_data; + + tmpi->len = sizeof(CISODirEntry) - 1; + tmpi->ext_attr_len = 0; + tmpi->flags = ISO_ATTR_DIR; + if (!tmpde->name[0]) + { + tmpi->name_len = 1; + tmpi->name = 1; + } + else + { + tmpi->name_len = StrLen(tmpde->name); + StrCopy(&tmpi->name, tmpde->name); + } + tmpi->len += tmpi->name_len; + + n = de(U8 *) + 1 - dir_blk_buf(U8 *); + n = (n + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; + FillU32Palindrome(&tmpi->size, n * DVD_BLK_SIZE); + FillU32Palindrome(&tmpi->loc, *_cur_blk); + tmpc->short_dir_blks = n; + tmpc->loc = *_cur_blk; + FillU32Palindrome(&dir_blk_buf->size, n * DVD_BLK_SIZE); + FillU32Palindrome(&dir_blk_buf->loc, *_cur_blk); + FillU16Palindrome(&tmpi->vol_seq_num, 1); + Date2ISO(&tmpi->date, tmpde->datetime); + if (write) + "%X:%s\n", *_cur_blk, tmpde->full_name; + if (write) + FBlkWrite(out_file, dir_blk_buf, *_cur_blk << 2, n << 2); + *_cur_blk += n; + + tmpi2->len = sizeof(CISODirEntry) - 1; + tmpi2->ext_attr_len = 0; + tmpi2->flags = ISO_ATTR_DIR; + if (!tmpde->name[0]) + { + tmpi2->name_len = 1; + tmpi->name = 1; + } + else + { + tmpi2->name_len = StrLen(tmpde->name) << 1; + ptr1 = &tmpi2->name; + ptr2 = &tmpde->name; + for (i = 0; i < tmpi2->name_len; i = i + 2) + { + ptr1++; + *ptr1++ = *ptr2++; + } + } + tmpi2->len += tmpi2->name_len; + n = de2(U8 *) + 1 - dir_blk_buf2(U8 *); + n = (n + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; + FillU32Palindrome(&tmpi2->size, n * DVD_BLK_SIZE); + FillU32Palindrome(&tmpi2->loc, *_cur_blk); + tmpc->long_dir_blks = n; + FillU32Palindrome(&dir_blk_buf2->size, n * DVD_BLK_SIZE); + FillU32Palindrome(&dir_blk_buf2->loc, *_cur_blk); + FillU16Palindrome(&tmpi2->vol_seq_num, 1); + Date2ISO(&tmpi2->date, tmpde->datetime); + if (write) + "%X:%s\n", *_cur_blk, tmpde->full_name; + if (write) + FBlkWrite(out_file, dir_blk_buf2, *_cur_blk << 2, n << 2); + *_cur_blk += n; + + Free(dir_blk_buf); + Free(dir_blk_buf2); + Free(buf); + return tmpi->name_len; +} + +I64 DVDTableLen(CDirEntry *tmpde, I64 *size1, I64 *size2, I64 cur_depth) +{ + //Returns depth + CDirEntry *tmpde1 = tmpde->sub; + I64 max_depth = cur_depth, i; + while (tmpde1) + { + if (tmpde1->attr & RS_ATTR_DIR) + { + *size1 += sizeof(CISOPathEntry) - 2 + (StrLen(tmpde1->name) + 1) & -0x2; + *size2 += sizeof(CISOPathEntry) - 2 + StrLen(tmpde1->name) << 1; + i = DVDTableLen(tmpde1, size1, size2, cur_depth + 1); + if (i > max_depth) + max_depth = i; + } + tmpde1 = tmpde1->next; + } + return max_depth; +} + +U0 DVDFillPathTable(CDirEntry *tmpde, + CISOPathEntry **_itabbuf, CISOPathEntry **_itabbuf2, + I64 parent_entry_num, Bool big_endian, I64 *first_free, + I64 cur_level, I64 output_level) +{ + U8 *ptr1, *ptr2; + I64 i; + CISOPathEntry *tabbuf = *_itabbuf, *tabbuf2 = *_itabbuf2; + CDirEntry *tmpde1 = tmpde->sub, *tmpde2; + CCDVDUserData *tmpc; + + if (cur_level == output_level) + { + while (tmpde1) + { + if (tmpde1->attr & RS_ATTR_DIR) + { + tmpc = tmpde1->user_data; + tmpc->path_entry_num = *first_free; + tabbuf->name_len = StrLen(tmpde1->name); + if (big_endian) + { + tabbuf->blk = EndianU32(tmpc->loc); + tabbuf->parent_entry_num = EndianU16(parent_entry_num); + } + else + { + tabbuf->blk = tmpc->loc; + tabbuf->parent_entry_num = parent_entry_num; + } + StrCopy(&tabbuf->name, tmpde1->name); + + tabbuf(U8 *) += sizeof(CISOPathEntry) - 2 + (StrLen(tmpde1->name) + 1) & -0x2; + + tabbuf2->name_len = StrLen(tmpde1->name) << 1; + if (big_endian) + { + tabbuf2->blk = EndianU32(tmpc->loc + tmpc->short_dir_blks); + tabbuf2->parent_entry_num = EndianU16(parent_entry_num); + } + else + { + tabbuf2->blk = tmpc->loc + tmpc->short_dir_blks; + tabbuf2->parent_entry_num = parent_entry_num; + } + ptr1 = &tabbuf2->name; + ptr2 = &tmpde1->name; + for (i = 0; i < tabbuf2->name_len; i = i + 2) + { + ptr1++; + *ptr1++ = *ptr2++; + } + tabbuf2(U8 *) += sizeof(CISOPathEntry) - 2 + StrLen(tmpde1->name) << 1; + *first_free += 1; + } + tmpde1 = tmpde1->next; + } + *_itabbuf = tabbuf; + *_itabbuf2 = tabbuf2; + } + tmpde1 = tmpde->sub; + while (tmpde1) + { + tmpde2 = tmpde1->next; + if (tmpde1->attr & RS_ATTR_DIR) + { + tmpc = tmpde1->user_data; + DVDFillPathTable(tmpde1, _itabbuf, _itabbuf2, tmpc->path_entry_num, + big_endian, first_free, cur_level + 1, output_level); + } + tmpde1 = tmpde2; + } +} + +public I64 ISO9660ISO(U8 *_filename = NULL, U8 *src_files_find_mask, + U8 *fu_flags = NULL, U8 *_stage2_filename = NULL) +{ + //See $LK,"::/Misc/DoDistro.ZC"$ + //Use "C:/Distro/*" if you want all files in the C:/Distro directory. + //Default flags are "+r" recurse. + CISOPriDesc *iso_pri = CAlloc(DVD_BLK_SIZE), + *iso_boot = CAlloc(DVD_BLK_SIZE), + *iso_sup = CAlloc(DVD_BLK_SIZE), + *iso_term = CAlloc(DVD_BLK_SIZE); + CDirEntry *headdir = CAlloc(sizeof(CDirEntry)); + I64 i, j, stage2_blk = (20 << 2 + 1 << 2 + DVD_BOOT_LOADER_SIZE / BLK_SIZE) >> 2, + stage2_size, cur_blk = 0, tabsize, tabsize2, first_free, max_depth, fuf_flags = 0; + U32 *d; + CElTorito *et = CAlloc(DVD_BLK_SIZE); + U8 *filename, *stage2_filename, + *stage1_buf = CAlloc(DVD_BOOT_LOADER_SIZE), + *zero_buf = CAlloc(DVD_BLK_SIZE); + CISOPathEntry *tabbuf = NULL, *tabbuf2 = NULL, *itabbuf, *itabbuf2; + CFile *out_file = NULL; + CISODirEntry *tmpi; + CCDVDUserData *tmpc; + + FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+r"); + FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags); + + if (!_filename) + _filename = blkdev.default_iso_filename; + filename = ExtDefault(_filename, "ISO"); + + if (_stage2_filename) + stage2_filename = FileNameAbs(_stage2_filename); + else + stage2_filename = NULL; + + headdir->attr = RS_ATTR_DIR; + headdir->sub = FilesFind(src_files_find_mask, fuf_flags); + headdir->datetime = Now; + headdir->user_data = CAlloc(sizeof(CCDVDUserData)); + tmpc = headdir->user_data; + tmpc->path_entry_num = 1; + + cur_blk = 20 << 2 >> 2; + if (stage2_filename) //preboot and bootloader + cur_blk += 1 + DVD_BOOT_LOADER_SIZE / DVD_BLK_SIZE; + DVDFileCreate2(out_file, headdir, &iso_pri->root_dir_record, &iso_sup->root_dir_record, + &cur_blk, headdir, FALSE, stage2_filename, &stage2_blk); + tabsize = sizeof(CISOPathEntry); + tabsize2 = sizeof(CISOPathEntry); + max_depth = DVDTableLen(headdir, &tabsize, &tabsize2, 1); + FillU32Palindrome(&iso_pri->path_table_size, tabsize); + FillU32Palindrome(&iso_sup->path_table_size, tabsize2); + tabsize = (tabsize + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; + cur_blk += tabsize << 1; + tabsize2 = (tabsize2 + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; + cur_blk += tabsize2 << 1; + + if (FileAttr(filename) & RS_ATTR_CONTIGUOUS) + out_file = FOpen(filename, "wc", cur_blk << 2); + else + out_file = FOpen(filename, "w", cur_blk << 2); + cur_blk = 0; + if (!out_file) + goto cf_done; + + while (cur_blk < 20 << 2 >> 2) + FBlkWrite(out_file, zero_buf, cur_blk++ << 2, 4); + + iso_pri->type = ISOT_PRI_VOL_DESC; + StrCopy(iso_pri->id, "CD001"); + iso_pri->version = 1; + FillU16Palindrome(&iso_pri->vol_set_size, 1); + FillU16Palindrome(&iso_pri->vol_seq_num, 1); + FillU16Palindrome(&iso_pri->log_block_size, DVD_BLK_SIZE); + iso_pri->file_structure_version = 1; + + iso_sup->type = ISOT_SUPPLEMENTARY_DESC; + StrCopy(iso_sup->id, "CD001"); + iso_sup->version = 1; + FillU16Palindrome(&iso_sup->vol_set_size, 1); + FillU16Palindrome(&iso_sup->vol_seq_num, 1); + FillU16Palindrome(&iso_sup->log_block_size, DVD_BLK_SIZE); + iso_sup->file_structure_version = 1; + + iso_boot->type = ISOT_BOOT_RECORD; + StrCopy(iso_boot->id, "CD001"); + iso_boot->version = 1; + StrCopy(iso_boot(U8 *) + 7, "EL TORITO SPECIFICATION"); + + cur_blk = 20 << 2 >> 2; + + if (stage2_filename) + { + d = iso_boot(U8 *) + 0x47; + *d = cur_blk; + et->w[0] = 1; + StrCopy(&et->w[2], "ZealOS"); + et->w[15] = 0xAA55; + j = 0; + for (i = 0; i < 16; i++) //Checksum + j += et->w[i]; + et->w[14] = -j; + et->bootable = 0x88; + et->media_type = 0; //0=no emu 2=1.44meg 4=hard drive + et->sect_count = 4; //5 seems like the limit, 4 is safer + et->load_rba = cur_blk + 1; + "%X: Pre Boot Blk\n", cur_blk; + FBlkWrite(out_file, et, cur_blk++ << 2, 4); + "%X: Boot Stage 1\n", cur_blk; + cur_blk += DVD_BOOT_LOADER_SIZE / DVD_BLK_SIZE; + } + + DVDFileCreate2(out_file, headdir, &iso_pri->root_dir_record, &iso_sup->root_dir_record, + &cur_blk, headdir, TRUE, stage2_filename, &stage2_blk); + + tabbuf = CAlloc(tabsize * DVD_BLK_SIZE); + iso_pri->type_l_path_table = cur_blk; + tabbuf->name_len = 2; //Fill-in root entry + tmpi = &iso_pri->root_dir_record; + tabbuf->blk = tmpi->loc.little; + tabbuf->parent_entry_num = 1; + tabbuf2 = CAlloc(tabsize2 * DVD_BLK_SIZE); + iso_sup->type_l_path_table = cur_blk + tabsize; + tabbuf2->name_len = 2; //Fill-in root entry + tmpi = &iso_sup->root_dir_record; + tabbuf2->blk = tmpi->loc.little; + tabbuf2->parent_entry_num = 1; + itabbuf = tabbuf + 1; + itabbuf2 = tabbuf2 + 1; + first_free = 2; + for (i = 1; i <= max_depth; i++) + DVDFillPathTable(headdir, &itabbuf, &itabbuf2, 1, FALSE, &first_free, 1, i); + "%X: Path Table 0\n", cur_blk; + FBlkWrite(out_file, tabbuf, cur_blk << 2, tabsize << 2); + cur_blk += tabsize; + "%X: Path Table 1\n", cur_blk; + FBlkWrite(out_file, tabbuf2, cur_blk << 2, tabsize2 << 2); + cur_blk += tabsize2; + + MemSet(tabbuf, 0, tabsize * DVD_BLK_SIZE); + iso_pri->type_m_path_table = EndianU32(cur_blk); + tabbuf->name_len = 2; //Fill-in root entry + tmpi = &iso_pri->root_dir_record; + tabbuf->blk = tmpi->loc.big; + tabbuf->parent_entry_num = EndianU16(1); + MemSet(tabbuf2, 0, tabsize2 * DVD_BLK_SIZE); + iso_sup->type_m_path_table = EndianU32(cur_blk + tabsize); + tabbuf2->name_len = 2; //Fill-in root entry + tmpi = &iso_sup->root_dir_record; + tabbuf2->blk = tmpi->loc.big; + tabbuf2->parent_entry_num = EndianU16(1); + itabbuf = tabbuf + 1; + itabbuf2 = tabbuf2 + 1; + first_free = 2; + for (i = 1; i <= max_depth; i++) + DVDFillPathTable(headdir, &itabbuf, &itabbuf2, 1, TRUE, &first_free, 1, i); + "%X: Path Table 2\n", cur_blk; + FBlkWrite(out_file, tabbuf, cur_blk << 2, tabsize << 2); + cur_blk += tabsize; + "%X: Path Table 3\n", cur_blk; + FBlkWrite(out_file, tabbuf2, cur_blk << 2, tabsize2 << 2); + cur_blk += tabsize2; + + DirTreeDel2(headdir); + FillU32Palindrome(&iso_pri->vol_space_size, cur_blk); + FillU32Palindrome(&iso_sup->vol_space_size, cur_blk); + FBlkWrite(out_file, iso_pri, 16 << 2, 4); + + iso_term->type = ISOT_TERMINATOR; + StrCopy(iso_term->id, "CD001"); + iso_term->version = 1; + if (stage2_filename) + { + FBlkWrite(out_file, iso_boot, 17 << 2, 4); + FBlkWrite(out_file, iso_sup, 18 << 2, 4); + FBlkWrite(out_file, iso_term, 19 << 2, 4); + stage2_size = (Size(stage2_filename, "+s") + DVD_BLK_SIZE - 1) / DVD_BLK_SIZE; + MemCopy(stage1_buf, BDVD_START, BDVD_END - BDVD_START); + *(BDVD_BLK_COUNT - BDVD_START + stage1_buf)(U16 *) = stage2_size; + *(BDVD_BLK_LO - BDVD_START + stage1_buf)(U32 *) = stage2_blk; + "$$RED$$!!! Boot Stage 2 !!! %X-%X$$FG$$\n", stage2_blk, stage2_blk + stage2_size - 1; + FBlkWrite(out_file, stage1_buf, 20 << 2 + 1 << 2, DVD_BOOT_LOADER_SIZE / BLK_SIZE); + } + else + { + FBlkWrite(out_file, iso_sup, 17 << 2, 4); + FBlkWrite(out_file, iso_term, 18 << 2, 4); + } + +cf_done: + FClose(out_file); + Free(tabbuf); + Free(tabbuf2); + Free(stage2_filename); + Free(filename); + Free(zero_buf); + Free(stage1_buf); + Free(et); + Free(iso_pri); + Free(iso_boot); + Free(iso_sup); + Free(iso_term); + return cur_blk; +} diff --git a/src/System/Externs.ZC b/src/System/Externs.ZC index ec79e31e..1cc001d9 100755 --- a/src/System/Externs.ZC +++ b/src/System/Externs.ZC @@ -47,6 +47,7 @@ extern I64 ExeDoc(CDoc *doc, I64 ccf_flags=0); extern I64 FindWiz(); extern I64 I64Get(U8 *message=NULL, I64 default=0, I64 lo=I64_MIN, I64 hi=I64_MAX); extern Bool GrPlot0(CDC *dc, I64 x, I64 y); +extern I64 ISO9660ISO(U8 *_filename = NULL, U8 *src_files_find_mask, U8 *fu_flags = NULL, U8 *_stage2_filename = NULL); extern CMenuEntry *MenuEntryFind(CMenu *haystack_menu, U8 *needle_full_name); extern CMenu *MenuFilePush(U8 *filename); extern U0 MenuPop(); @@ -58,6 +59,7 @@ extern Bool PopUpCancelOk(U8 *header=NULL, U8 *footer=NULL); extern I64 PopUpColor(U8 *header=NULL, Bool allow_transparent=TRUE, Bool allow_default=TRUE); extern I64 PopUpColorDither(U8 *header=NULL); extern I64 PopUpColorLighting(U8 *header=NULL); +extern I64 PopUpEd(U8 *filename=NULL, CTask *parent=NULL, CTask **_pu_task=NULL); extern I64 PopUpFile(U8 *filename, Bool warn_ext=TRUE, CTask *parent=NULL, CTask **_pu_task=NULL); extern Bool PopUpForm(U8 *_d, U8 *class_name=lastclass, I64 dof_flags=DOF_SIZE_MIN, U8 *header=NULL, U8 *footer=NULL); extern I64 PopUpI64Get(U8 *message, I64 default, I64 lo=I64_MIN, I64 hi=I64_MAX);