LTCD_070816.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:45:20 +02:00
1 parent d14bbc24f9
commit 0e9364ff4c
506 files changed
+157705 -41812

No files matched your search

+543
View File
@@ -0,0 +1,543 @@
#help_index "File/CD DVD"
void FillBigEndianU2(U2 *dst,U2 w)
{
U2 *src=&w;
dst->u1[0]=src->u1[1];
dst->u1[1]=src->u1[0];
}
void FillBigEndianU4(U4 *dst,U8 d)
{
U8 *src=&d;
dst->u1[0]=src->u1[3];
dst->u1[1]=src->u1[2];
dst->u1[2]=src->u1[1];
dst->u1[3]=src->u1[0];
}
void FillU2Palindrome(U2Palindrome *dst,U2 w)
{
FillBigEndianU2(&dst->big,w);
dst->little=w;
}
void FillU4Palindrome(U4Palindrome *dst,U8 d)
{
FillBigEndianU4(&dst->big,d);
dst->little=d;
}
class CCdUserData
{
U8 location,path_entry_num,
short_dir_blks,long_dir_blks;
};
U8 DoCreateCDFile(LTFile *out_file,LTDirEntry *tempm,
ISODirEntry *tempi,ISODirEntry *tempi2,
U8 *cur_blk,
LTDirEntry *parent,BoolU4 write)
{
CCdUserData *tempc;
LTDirEntry *tempm1,*tempm2;
LTFile *in_file;
U1 *buf=MAlloc(CD_BLK_SIZE),*ptr1,*ptr2;
ISODirEntry *dir_blk_buf=MAllocZ(CD_BLK_SIZE*128),
*de=dir_blk_buf,*de1;
ISODirEntry *dir_blk_buf2=MAllocZ(CD_BLK_SIZE*128),
*de2=dir_blk_buf2,*de12;
U8 i,n;
tempc=parent->user_data;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,tempm->datetime);
de->flags=ISO_ATTR_DIR;
de->name_len=1;
de->name=0;
de->length+=de->name_len;
de+=de->length;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU4Palindrome(&de->location,tempc->location);
FillU4Palindrome(&de->size,tempc->short_dir_blks*CD_BLK_SIZE);
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,parent->datetime);
de->flags=ISO_ATTR_DIR;
de->name_len=1;
de->name=1;
de->length+=de->name_len;
de+=de->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,tempm->datetime);
de2->flags=ISO_ATTR_DIR;
de2->name_len=1;
de2->name=0;
de2->length=de2->length+de2->name_len;
de2+=de2->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU4Palindrome(&de2->location,tempc->location+tempc->short_dir_blks);
FillU4Palindrome(&de2->size,tempc->long_dir_blks*CD_BLK_SIZE);
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,parent->datetime);
de2->flags=ISO_ATTR_DIR;
de2->name_len=1;
de2->name=1;
de2->length+=de2->name_len;
de2+=de2->length;
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (!write) tempm1->user_data=MAllocZ(sizeof(CCdUserData));
de1=de;
de12=de2;
if (tempm1->attr & LT_ATTR_DIR) {
n=DoCreateCDFile(out_file,tempm1,de,de2,cur_blk,tempm,write);
de+=sizeof(ISODirEntry)-1+n;
de2+=sizeof(ISODirEntry)-1+n<<1;
} else {
tempc=tempm1->user_data;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU4Palindrome(&de->location,*cur_blk);
tempc->location=*cur_blk;
if (write)
coutln *cur_blk,":",tempm1->full_name;
FillU4Palindrome(&de->size,tempm1->size);
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,tempm1->datetime);
de->flags=0;
de->name_len=StrLen(tempm1->name);
StrCpy(&de->name,tempm1->name);
de->length=de->length+de->name_len;
de+=de->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU4Palindrome(&de2->location,*cur_blk);
FillU4Palindrome(&de2->size,tempm1->size);
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,tempm1->datetime);
de2->flags=0;
de2->name_len=StrLen(tempm1->name)<<1;
ptr1=&de2->name;
ptr2=&tempm1->name;
for (i=0;i<de2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
de2->length+=de2->name_len;
de2+=de2->length;
in_file=FOpen(tempm1->full_name,"r");
for (i=0;i<(FSize(in_file)+CD_BLK_SIZE-1)/CD_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)%4;
MemSet(buf,0,CD_BLK_SIZE);
}
if (write) {
FRBlks(in_file,buf,i<<2,n);
FWBlks(out_file,buf,(*cur_blk)<<2,n);
}
*cur_blk+=1;
}
FClose(in_file);
}
if ((de1-dir_blk_buf)/CD_BLK_SIZE!=
(de -dir_blk_buf)/CD_BLK_SIZE) {
i=de1->length;
MemCpy(buf,de1,i);
MemSet(de1,0,i);
de=dir_blk_buf+((de-dir_blk_buf)/CD_BLK_SIZE)*CD_BLK_SIZE;
MemCpy(de,buf,i);
de+=i;
}
if ((de12-dir_blk_buf2)/CD_BLK_SIZE!=
(de2 -dir_blk_buf2)/CD_BLK_SIZE) {
i=de12->length;
MemCpy(buf,de12,i);
MemSet(de12,0,i);
de2=dir_blk_buf2+((de2-dir_blk_buf2)/CD_BLK_SIZE)*CD_BLK_SIZE;
MemCpy(de2,buf,i);
de2+=i;
}
tempm1=tempm2;
}
tempc=tempm->user_data;
tempi->length=sizeof(ISODirEntry)-1;
tempi->ext_attr_length=0;
tempi->flags=ISO_ATTR_DIR;
if (!tempm->name[0]) {
tempi->name_len=1;
tempi->name=1;
} else {
tempi->name_len=StrLen(tempm->name);
StrCpy(&tempi->name,tempm->name);
}
tempi->length+=tempi->name_len;
n=de+1-dir_blk_buf;
n=(n+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU4Palindrome(&tempi->size,n*CD_BLK_SIZE);
FillU4Palindrome(&tempi->location,*cur_blk);
tempc->short_dir_blks=n;
tempc->location=*cur_blk;
FillU4Palindrome(&dir_blk_buf->size,n*CD_BLK_SIZE);
FillU4Palindrome(&dir_blk_buf->location,*cur_blk);
FillU2Palindrome(&tempi->volume_sequence_num,1);
LTDateToISO(&tempi->date,tempm->datetime);
if (write)
coutln *cur_blk,":",tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf,(*cur_blk)<<2,n<<2);
*cur_blk+=n;
tempi2->length=sizeof(ISODirEntry)-1;
tempi2->ext_attr_length=0;
tempi2->flags=ISO_ATTR_DIR;
if (!tempm->name[0]) {
tempi2->name_len=1;
tempi->name=1;
} else {
tempi2->name_len=StrLen(tempm->name)<<1;
ptr1=&tempi2->name;
ptr2=&tempm->name;
for (i=0;i<tempi2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
}
tempi2->length+=tempi2->name_len;
n=de2+1-dir_blk_buf2;
n=(n+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU4Palindrome(&tempi2->size,n*CD_BLK_SIZE);
FillU4Palindrome(&tempi2->location,*cur_blk);
tempc->long_dir_blks=n;
FillU4Palindrome(&dir_blk_buf2->size,n*CD_BLK_SIZE);
FillU4Palindrome(&dir_blk_buf2->location,*cur_blk);
FillU2Palindrome(&tempi2->volume_sequence_num,1);
LTDateToISO(&tempi2->date,tempm->datetime);
if (write)
coutln *cur_blk,":",tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf2,(*cur_blk)<<2,n<<2);
*cur_blk+=n;
Free(dir_blk_buf);
Free(dir_blk_buf2);
Free(buf);
return tempi->name_len;
}
U8 CDTableLength(LTDirEntry *tempm,U8 *size1,U8 *size2,U8 cur_depth)
//returns depth
{
LTDirEntry *tempm1=tempm->sub;
U8 max_depth=cur_depth,i;
while (tempm1) {
if (tempm1->attr & LT_ATTR_DIR) {
*size1+=sizeof(ISOPathTableEntry)-2+((StrLen(tempm1->name)+1) & -0x2);
*size2+=sizeof(ISOPathTableEntry)-2+StrLen(tempm1->name)<<1;
i=CDTableLength(tempm1,size1,size2,cur_depth+1);
if (i>max_depth) max_depth=i;
}
tempm1=tempm1->next;
}
return max_depth;
}
void CDFillPathTable(LTDirEntry *tempm,
ISOPathTableEntry *itabbuf,ISOPathTableEntry *itabbuf2,
U8 parent_entry_num,BoolU4 big_endian,U8 *first_free,I8 cur_level,I8 output_level)
{
I1 *ptr1,*ptr2;
U8 i;
ISOPathTableEntry *tabbuf=*itabbuf;
ISOPathTableEntry *tabbuf2=*itabbuf2;
LTDirEntry *tempm1=tempm->sub,*tempm2;
CCdUserData *tempc;
if (cur_level==output_level) {
while (tempm1) {
if (tempm1->attr & LT_ATTR_DIR) {
tempc=tempm1->user_data;
tempc->path_entry_num=*first_free;
tabbuf->name_len=StrLen(tempm1->name);
if (big_endian) {
FillBigEndianU4(&tabbuf->blk,tempc->location);
FillBigEndianU2(&tabbuf->parent_entry_num,parent_entry_num);
} else {
tabbuf->blk=tempc->location;
tabbuf->parent_entry_num=parent_entry_num;
}
StrCpy(&tabbuf->name,tempm1->name);
tabbuf+=sizeof(ISOPathTableEntry)-2+
((StrLen(tempm1->name)+1) & -0x2);
tabbuf2->name_len=StrLen(tempm1->name)<<1;
if (big_endian) {
FillBigEndianU4(&tabbuf2->blk,tempc->location+tempc->short_dir_blks);
FillBigEndianU2(&tabbuf2->parent_entry_num,parent_entry_num);
} else {
tabbuf2->blk=tempc->location+tempc->short_dir_blks;
tabbuf2->parent_entry_num=parent_entry_num;
}
ptr1=&tabbuf2->name;
ptr2=&tempm1->name;
for (i=0;i<tabbuf2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
tabbuf2+=sizeof(ISOPathTableEntry)-2+
StrLen(tempm1->name)<<1;
*first_free+=1;
}
tempm1=tempm1->next;
}
*itabbuf=tabbuf;
*itabbuf2=tabbuf2;
}
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
tempc=tempm1->user_data;
CDFillPathTable(tempm1,itabbuf,itabbuf2,tempc->path_entry_num,
big_endian,first_free,cur_level+1,output_level);
}
tempm1=tempm2;
}
}
class ElTorito
{
U2 w[16];
U1 bootable; //88=bootable 00=not bootable
U1 media_type; //0=no emulation 4=hard disk
U2 load_seg; //0000->07C0
U1 sys_type;
U1 zero;
U2 sector_cnt;
U4 load_rba; //start address of virtual disk
U1 zero2[20];
};
public U8 CreateCDFile(I1 *filename,I1 src_drive,
I1 *bootfile=NULL)
{
ISOPrimaryDescriptor *iso =MAllocZ(CD_BLK_SIZE),
*iso1=MAllocZ(CD_BLK_SIZE),
*iso2=MAllocZ(CD_BLK_SIZE),
*iso3=MAllocZ(CD_BLK_SIZE);
LTDirEntry *rootdir=MAllocZ(sizeof(LTDirEntry));
U8 cur_blk=0,bsize,tabsize,tabsize2,first_free,max_depth;
U4 *d;
I1 mask[8];
I1 *filename2;
ElTorito *et=MAllocZ(CD_BLK_SIZE);
U1 *buf=MAllocZ(CD_BLK_SIZE),
*bootfile_buf=NULL;
ISOPathTableEntry *tabbuf=NULL,*tabbuf2=NULL,
*itabbuf,*itabbuf2;
BoolU4 okay=TRUE;
U8 i,j;
LTFile *out_file=NULL;
ISODirEntry *tempi;
CCdUserData *tempc;
if (!filename)
filename=default_iso_name;
filename2=DefaultExtension(filename,"ISO");
SPrintF(mask,"%c:/*",src_drive);
if (bootfile)
bootfile_buf=ReadFile(bootfile,&bsize);
rootdir->attr=LT_ATTR_DIR;
rootdir->sub=FindFiles(mask,1<<FUf_RECURSE);
rootdir->datetime=GetCurTimeLTDate;
rootdir->user_data=MAllocZ(sizeof(CCdUserData));
tempc=rootdir->user_data;
tempc->path_entry_num=1;
if (okay) {
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf)
cur_blk+=2;
DoCreateCDFile(out_file,rootdir,
&iso->root_directory_record,
&iso2->root_directory_record,
&cur_blk,rootdir,FALSE);
tabsize=sizeof(ISOPathTableEntry);
tabsize2=sizeof(ISOPathTableEntry);
max_depth=CDTableLength(rootdir,&tabsize,&tabsize2,1);
FillU4Palindrome(&iso->path_table_size,tabsize);
FillU4Palindrome(&iso2->path_table_size,tabsize2);
tabsize=(tabsize+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize<<1;
tabsize2=(tabsize2+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize2<<1;
}
if (okay) {
if (FileAttr(filename2) & LT_ATTR_CONTIGUOUS)
out_file=FOpen(filename2,"wc",cur_blk<<2);
else
out_file=FOpen(filename2,"w",cur_blk<<2);
if (!out_file)
okay=FALSE;
}
if (okay) {
cur_blk=0;
while (cur_blk<CD_FILE_OFFSET>>2) {
FWBlks(out_file,buf,cur_blk<<2,4);
cur_blk++;
}
iso->type=ISOT_PRIMARY_VOLUME_DESC;
StrCpy(iso->id,"CD001");
iso->version=1;
FillU2Palindrome(&iso->volume_set_size,1);
FillU2Palindrome(&iso->volume_sequence_number,1);
FillU2Palindrome(&iso->logical_block_size,CD_BLK_SIZE);
iso->file_structure_version=1;
iso2->type=ISOT_SUPPLEMENTARY_DESC;
StrCpy(iso2->id,"CD001");
iso2->version=1;
FillU2Palindrome(&iso2->volume_set_size,1);
FillU2Palindrome(&iso2->volume_sequence_number,1);
FillU2Palindrome(&iso2->logical_block_size,CD_BLK_SIZE);
iso2->file_structure_version=1;
iso1->type=ISOT_BOOT_RECORD;
StrCpy(iso1->id,"CD001");
iso1->version=1;
StrCpy(iso1+7,"EL TORITO SPECIFICATION");
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf) {
d=iso1+0x47;
*d=cur_blk;
et->w[0]=1;
StrCpy(&et->w[2],"LoseThos");
et->w[15]=0xAA55;
j=0;
for (i=0;i<16;i++) //Checksum
j+=et->w[i];
et->w[14]=-j;
if (bootfile_buf)
et->bootable=0x88;
et->media_type=0; //0=no emu 2=1.44meg 4=hard drive
et->sector_cnt=4;
et->load_rba=cur_blk+1;
coutln cur_blk,": Pre Boot Blk";
FWBlks(out_file,et,cur_blk<<2,4);
cur_blk++;
coutln cur_blk,": Boot Blk";
FWBlks(out_file,bootfile_buf,cur_blk<<2,4);
cur_blk++;
}
DoCreateCDFile(out_file,rootdir,
&iso->root_directory_record,
&iso2->root_directory_record,
&cur_blk,rootdir,TRUE);
tabbuf=MAllocZ(tabsize*CD_BLK_SIZE);
iso->type_l_path_table=cur_blk;
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_directory_record;
tabbuf->blk=tempi->location.little;
tabbuf->parent_entry_num=1;
tabbuf2=MAllocZ(tabsize2*CD_BLK_SIZE);
iso2->type_l_path_table=cur_blk+tabsize;
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_directory_record;
tabbuf2->blk=tempi->location.little;
tabbuf2->parent_entry_num=1;
itabbuf=tabbuf+sizeof(ISOPathTableEntry);
itabbuf2=tabbuf2+sizeof(ISOPathTableEntry);
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,FALSE,&first_free,1,i);
coutln cur_blk,": Path Table 0";
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
coutln cur_blk,": Path Table 1";
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
MemSet(tabbuf,0,tabsize*CD_BLK_SIZE);
FillBigEndianU4(&iso->type_m_path_table,cur_blk);
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_directory_record;
tabbuf->blk=tempi->location.big;
FillBigEndianU2(&tabbuf->parent_entry_num,1);
MemSet(tabbuf2,0,tabsize2*CD_BLK_SIZE);
FillBigEndianU4(&iso2->type_m_path_table,cur_blk+tabsize);
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_directory_record;
tabbuf2->blk=tempi->location.big;
FillBigEndianU2(&tabbuf2->parent_entry_num,1);
itabbuf=tabbuf+sizeof(ISOPathTableEntry);
itabbuf2=tabbuf2+sizeof(ISOPathTableEntry);
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,TRUE,&first_free,1,i);
coutln cur_blk,": Path Table 2";
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
coutln cur_blk,": Path Table 3";
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
DelLTDirList(rootdir); //TODO: Free user_data
FillU4Palindrome(&iso->volume_space_size,cur_blk);
FillU4Palindrome(&iso2->volume_space_size,cur_blk);
FWBlks(out_file,iso,16<<2,4);
iso3->type=ISOT_TERMINATOR;
StrCpy(iso3->id,"CD001");
iso3->version=1;
if (bootfile_buf) {
FWBlks(out_file,iso1,17<<2,4);
FWBlks(out_file,iso2,18<<2,4);
FWBlks(out_file,iso3,19<<2,4);
} else {
FWBlks(out_file,iso2,17<<2,4);
FWBlks(out_file,iso3,18<<2,4);
}
} else
cur_blk=0;
FClose(out_file);
Free(tabbuf);
Free(tabbuf2);
Free(et);
Free(bootfile_buf);
Free(iso);
Free(iso1);
Free(iso2);
Free(iso3);
Free(filename2);
return cur_blk;
}
#help_index ""