void MapDrive(I1 ch,LTPartition *p) { drive_to_partition[ToUpper(ch)-'A']=p; p->drive=ToUpper(ch); } BoolU4 Drive(I1 drive_letter) { LTPartition *p; LTBlkDev *bdev; BoolU4 different=FALSE; LTPartition *new_partition=DriveToPartition(drive_letter); if (!new_partition) { PutSysText("ST_INVALID_DRIVE"); return FALSE; } if (new_partition!=Fs->cur_partition) { different=TRUE; Fs->cur_partition=new_partition; } p=Fs->cur_partition; CheckLTPartition(p); bdev=p->bdev; CheckLTBlkDev(bdev); if (different) { if ((bdev->flags & LTBDF_REMOVABLE) && !(bdev->flags & LTBDF_INITIALIZED) ) ChangeDisk(p->drive); if (bdev->type==LTBDT_RAM || bdev->type==LTBDT_FILE) InitBlkDev(bdev,TRUE); } Free(Fs->cur_dir); Fs->cur_dir=NewString("/"); if (p->type==PT_ISO9660 || p->type==PT_LT) return TRUE; else return FALSE; } BoolU4 Cd(I1 *name,BoolU4 make_dirs=FALSE) { I8 maxlen; BoolU4 result=TRUE; I1 *buf2,*buf3,*buf,*hdir; LTPartition *p; U8 cur_dir_cluster=0; if (*name && name[1]==':') { if (*name==':') { if (Fs->cur_partition!=default_partition) if (!Drive(*name)) return FALSE; } else { if (Fs->cur_partition!= DriveToPartition(*name)) if (!Drive(*name)) return FALSE; } name+=2; } if (*name=='/') { Free(Fs->cur_dir); Fs->cur_dir=NewString("/"); name++; } buf2=MStringUtil(name, SU_REMOVE_LEADING|SU_REMOVE_TRAILING| SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS); maxlen=StrLen(Fs->cur_dir)+1+StrLen(buf2)+1; buf3=MAlloc(maxlen); buf=MAlloc(maxlen); StrCpy(buf3,Fs->cur_dir); while (*buf2 && result) { RemoveFirstSeg(buf2,"/",buf); if (!*buf) StrCpy(buf3,"/"); else if (!StrCmp(buf,"..")) { RemoveLastSeg(buf3,"/",buf); if (!*buf3) StrCpy(buf3,"/"); } else if (!StrCmp(buf,".")) { ; } else if (*buf) { if (!StrCmp(buf,"HOME")) { hdir=HomeDirString; result=Cd(hdir); Free(buf3); buf3=MAlloc(maxlen+StrLen(hdir)); StrCpy(buf3,hdir+2); Free(hdir); } else { p=Fs->cur_partition; cur_dir_cluster=NameToDirCluster(p,buf3,TRUE); if (p->type==PT_LT) result=CdLT(buf,cur_dir_cluster); else if (p->type==PT_ISO9660) result=CdISO(buf,cur_dir_cluster); else result=FALSE; if (!result && make_dirs) { Free(Fs->cur_dir); Fs->cur_dir=NewString(buf3); result=MkDir(buf); } if (result) { if (StrCmp(buf3,"/")) StrCat(buf3,"/"); StrCat(buf3,buf); } } } } Free(Fs->cur_dir); Fs->cur_dir=NewString(buf3); Free(buf); Free(buf2); Free(buf3); return result; } void DelLTFileAccess(LTFileAccess *fa) { LTBlkDev *bdev; if (!fa) return; bdev=fa->old_partition->bdev; if (!(bdev->flags & LTBDF_INIT_IN_PROGRESS)) { if (fa->old_dir) { Drive(PartitionToDrive(fa->old_partition)); Cd(fa->old_dir); } } else { Fs->cur_partition=fa->old_partition; Free(Fs->cur_dir); Fs->cur_dir=NewString("/"); } Free(fa->old_dir); Free(fa->mask); Free(fa); } LTFileAccess *NewLTFileAccess(I1 *mask,BoolU4 make_mask=FALSE,BoolU4 make_dirs=FALSE) { BoolU4 valid=TRUE; I1 *buf,*my_mask,*temp_mask; BoolU4 old_silent; LTFileAccess *fa=MAllocZ(sizeof(LTFileAccess)); my_mask=MStringUtil(mask, SU_REMOVE_LEADING|SU_REMOVE_TRAILING| SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS); temp_mask=my_mask; fa->old_dir=NewString(Fs->cur_dir); fa->old_partition=Fs->cur_partition; if (*my_mask && my_mask[1]==':') { if (Fs->cur_partition!=DriveToPartition(*my_mask)) if (!Drive(*my_mask)) valid=FALSE; my_mask+=2; } if (StrStr(my_mask,"HOME")) { //TODO if (Fs->cur_partition!=DriveToPartition(':')) Drive(':'); } fa->p=Fs->cur_partition; CheckLTPartition(fa->p); buf=NewString(my_mask); fa->mask=MAlloc(StrLen(buf)+1); RemoveLastSeg(buf,"/",fa->mask); if (*my_mask=='/' && !*buf) StrCpy(buf,"/"); if (*buf) if (!Cd(buf,make_dirs)) valid=FALSE; if (valid && make_mask) { if (!make_dirs || CheckFileName(fa->mask)) { old_silent=Silent(ON); if (Cd(fa->mask,make_dirs)) { Free(fa->mask); fa->mask=NewString("*"); } Silent(old_silent); } } Free(buf); Free(temp_mask); if (!valid) { DelLTFileAccess(fa); fa=NULL; // throw(EXCEPT_FILE); } return fa; } LTDirEntry *FindFiles(I1 *wild,U8 *fuf_flags=NULL) { U8 my_flags=0; LTDirEntry *result=NULL; LTFileAccess *fa=NewLTFileAccess(wild,TRUE); if (!fuf_flags) fuf_flags=&my_flags; if (fa) { result=SysFindFiles(fa->mask,fuf_flags); DelLTFileAccess(fa); } return result; } BoolU4 IsDir(I1 *dir_name) { BoolU4 result=FALSE; I1 *mask=MSPrintF("%s/*",dir_name); BoolU4 old_silent=Silent(ON); LTFileAccess *fa=NewLTFileAccess(mask); if (fa) { result=TRUE; DelLTFileAccess(fa); } Free(mask); Silent(old_silent); return result; } void Dir(I1 *wild=NULL,BoolU4 full=FALSE) { I1 *w; LTFileAccess *fa; if (!wild) w=NewString("*"); //We must do this because of bug that prevents string defaults else w=NewString(wild); fa=NewLTFileAccess(w,TRUE); if (fa) { DirLT(fa->mask,full); DelLTFileAccess(fa); } Free(w); } void Del(I1 *wild,BoolU4 print_msg=TRUE) { LTFileAccess *fa=NewLTFileAccess(wild); if (fa) { if (fa->p->type==PT_LT) DelLTFiles(fa->p,Fs->cur_dir,fa->mask,FALSE,print_msg); DelLTFileAccess(fa); } } U1 *ReadFile(I1 *filename,U8 *size=NULL,U8 *attr=NULL,BoolU4 raw=FALSE) { SysHashEntry *temph,**temph1; I1 *absname; U1 *result=NULL; U8 size2=0,attr2=0; LTFileAccess *fa; ArcCompressStruct *ac=NULL; if (attr) *attr=0; absname=AbsoluteFileName(filename); if (!raw && (temph=FindHashEntry(absname,adam_tss->hash_table,HTT_FILE))) { if (FileAttr(absname) & LT_ATTR_COMPRESSED) { ac=temph->user0; if (size) *size=ac->expanded_size; if (attr) *attr=FileAttr(absname,*attr); result=ExpandBuf(ac); } else { //Not implimented result=MAlloc(temph->user1+1); MemCpy(result,temph->user0,temph->user1); result[temph->user1]=0; //Terminate if (size) *size=temph->user1; } } else { fa=NewLTFileAccess(absname); if (fa) { if (fa->p->type==PT_LT) result=ReadLTFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); else if (fa->p->type==PT_ISO9660) result=ReadISOFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); if (Fs->cur_partition->type==PT_LT) result=ReadLTFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); else if (fa->p->type==PT_ISO9660) result=ReadISOFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); } if (!result) cout filename," ",SysText("ST_FILE_NOT_FOUND"); DelLTFileAccess(fa); } if (size) *size=size2; if (attr) *attr=attr2; if (!raw && attr2 & LT_ATTR_RESIDENT) { temph=AMAllocZ(sizeof(SysHashEntry)); temph->string=ANewString(absname); temph->type=HTT_FILE; temph->use_cnt=0; temph->source_link=NULL; temph->user0=AMAllocIdentical(ac); temph->user1=size2; temph1=FindHashBucket(temph->string,adam_tss->hash_table); temph->next=*temph1; *temph1=temph; } Free(ac); } Free(absname); return result; } I1 *ReadTextFile(I1 *filename,U8 *attr=NULL) { return ReadFile(filename,NULL,attr); } BoolU4 FindFile(I1 *filename,LTDirEntry *rde=NULL, BoolU4 dir_only=FALSE,BoolU4 file_only=FALSE,BoolU4 scan_parents=FALSE) { U8 cur_dir_cluster; BoolU4 result=FALSE; LTDirEntry de; LTFileAccess *fa=NewLTFileAccess(filename); if (fa) { cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE); if (fa->p->type==PT_LT) result=FindLTFile(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only,TRUE); else if (fa->p->type==PT_ISO9660) result=FindISOFile(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only,TRUE); if (scan_parents) { while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE); if (fa->p->type==PT_LT) result=FindLTFile(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only,TRUE); else if (fa->p->type==PT_ISO9660) result=FindISOFile(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only,TRUE); } } DelLTFileAccess(fa); } if (result && rde) MemCpy(rde,&de,sizeof(LTDirEntry)); return result; } U8 WriteFile(I1 *filename,U1 *fbuf, U8 size,LTDate LTdatetime=0,U8 attr=0,BoolU4 raw=FALSE) { U8 c=0; SysHashEntry *temph,**temph1; LTFileAccess *fa=NewLTFileAccess(filename); ArcCompressStruct *ac=NULL; I1 *absname=AbsoluteFileName(filename); if (fa) { if (fa->p->type==PT_LT) c=WriteLTFile(fa->p,Fs->cur_dir,fa->mask, fbuf,size,LTdatetime,attr,raw,&ac); if (temph=FindHashEntry(absname,adam_tss->hash_table,HTT_FILE)) { AFree(temph->user0); if (!raw && ac && attr & LT_ATTR_RESIDENT) { temph->user0=AMAllocIdentical(ac); temph->user1=size; } else { temph->user0=0; temph->type=HTT_INVALID; } } else if (!raw && ac && attr & LT_ATTR_RESIDENT) { temph=AMAllocZ(sizeof(SysHashEntry)); temph->string=ANewString(absname); temph->type=HTT_FILE; temph->use_cnt=0; temph->source_link=NULL; temph->user0=AMAllocIdentical(ac); temph->user1=size; temph1=FindHashBucket(temph->string,adam_tss->hash_table); temph->next=*temph1; *temph1=temph; } Free(ac); DelLTFileAccess(fa); } Free(absname); return c; } void WriteTextFile(I1 *filename,I1 *st,U8 attr=0) { WriteFile(filename,st,StrLen(st),0,attr); } void FAllocFile(LTFile *f,U8 cnt,BoolU4 contiguous) { LTPartition *fp=f->p; LTFileAccess *fa=NewLTFileAccess(f->de.full_name); f->de.cluster=AllocClusters(fp,0,(cnt+fp->spc-1)/fp->spc,contiguous,TRUE); f->de.size=BLK_SIZE*cnt; f->de.expanded_size=f->de.size; if (fa) { NewLTDirEntry(fa->p,Fs->cur_dir,&f->de,TRUE); DelLTFileAccess(fa); } f->flags&=~LTF_NEW_FILE; } U8 FSize(LTFile *f) { if (f) return f->de.size; else return 0; } void FSync(LTFile *f) { if (f->flags & LTF_BUF_DIRTY) { WClusters(f->p,f->cluster_buf,f->cluster,1,TRUE,TRUE); f->flags&=~LTF_BUF_DIRTY; } disk_status_display.u2[1]=0; } LTFile *FOpen(I1 *filename,I1 *flags,U8 cnt=0) { //allows flags "r","w","w+" and "c" (contiguous) LTFile *f=AMAllocZ(sizeof(LTFile)); LTFileAccess *fa; I1 *full_name,*full_name2; BoolU4 contiguous=Occurrences(flags,'c'); f->cluster=INVALID_CLUSTER; f->file_ptr=0; f->fblk_num=0; if (cnt) f->max_blk=cnt-1; else f->max_blk=INVALID_CLUSTER; f->file_cluster_num=INVALID_CLUSTER; full_name2=AbsoluteFileName(filename); full_name=ANewString(full_name2); Free(full_name2); f->p=DriveToPartition(*full_name); if (contiguous) { f->flags|=LTF_CONTIGUOUS; if (f->p->type!=PT_LT) { if (!(FileAttr(filename) & LT_ATTR_CONTIGUOUS)) throw(EXCEPT_FILE,60); } } f->cluster_buf=AMAllocZ(f->p->spc*BLK_SIZE); if (Occurrences(flags,'w')) { f->flags=f->flags|LTF_WRITE|LTF_NEEDS_WRITE; if (Occurrences(flags,'+')) { if (FindFile(full_name,&f->de,FALSE,TRUE)) { f->de.full_name=full_name; if (contiguous) f->max_blk=(FSize(f)+BLK_SIZE-1)/BLK_SIZE-1; return f; } } else Del(full_name,FALSE); f->de.full_name=full_name; f->flags|=LTF_NEW_FILE; fa=NewLTFileAccess(full_name); if (fa) { StrCpy(f->de.name,fa->mask); DelLTFileAccess(fa); if (cnt) FAllocFile(f,cnt,contiguous); if (!contiguous || cnt) return f; } } else { if (FindFile(full_name,&f->de,FALSE,TRUE)) { f->de.full_name=full_name; if (contiguous) f->max_blk=(FSize(f)+BLK_SIZE-1)/BLK_SIZE-1; return f; } } AFree(f->cluster_buf); AFree(full_name); AFree(f); return NULL; } void FClose(LTFile *f) { LTFileAccess *fa; if (f) { FSync(f); if (f->flags & LTF_NEEDS_WRITE) { fa=NewLTFileAccess(f->de.full_name); if (fa) { if (!(f->flags & LTF_USE_OLD_DATETIME)) f->de.datetime=GetCurTimeLTDate; if (f->flags & LTF_NEW_FILE) NewLTDirEntry(fa->p,Fs->cur_dir,&f->de,TRUE); else NewLTDirEntry(fa->p,Fs->cur_dir,&f->de,FALSE); DelLTFileAccess(fa); } else throw(EXCEPT_FILE,40); } AFree(f->cluster_buf); AFree(f->de.full_name); AFree(f); } } U8 FSetCluster(LTFile *f,U8 c,U8 blk,BoolU4 read) { if (f->cluster!=c) { if (f->flags & LTF_BUF_DIRTY) { WClusters(f->p,f->cluster_buf,f->cluster,1,TRUE,TRUE); f->flags=f->flags & ~LTF_BUF_DIRTY; } f->cluster=c; f->file_cluster_num=blk/f->p->spc; if (read) c=RClusters(f->p,f->cluster_buf,c,1,TRUE,TRUE); } return c; } BoolU4 FRBlks(LTFile *f,U1 *buf,U8 blk=LTFB_NEXT_BLK,U8 cnt=1) { LTPartition *p=f->p; U8 spc=p->spc,i,j,c=f->de.cluster; if (!f || !p) return FALSE; if (blk==LTFB_NEXT_BLK) blk=f->fblk_num; if (blk+cnt-1>f->max_blk) return FALSE; if (!cnt) return TRUE; disk_status_display.u2[1]=cnt/spc; if (f->flags & LTF_CONTIGUOUS) { RBlks(p,buf,ClusterBlk(p,c)+blk,cnt,TRUE); blk+=cnt; } else { i=blk/spc; if (i>=f->file_cluster_num) { c=f->cluster; i-=f->file_cluster_num; } if (i) c=NextClusterNum(p,c,i,TRUE); i=blk%spc; if (i) { c=FSetCluster(f,c,blk,TRUE); j=(cntcluster_buf+BLK_SIZE*i,j*BLK_SIZE); buf+=j*BLK_SIZE; cnt-=j; blk+=j; } while (cnt>=spc) { c=FSetCluster(f,c,blk,TRUE); MemCpy(buf,f->cluster_buf,spc*BLK_SIZE); buf+=spc*BLK_SIZE; cnt-=spc; blk+=spc; } if (cnt) { c=FSetCluster(f,c,blk,TRUE); MemCpy(buf,f->cluster_buf,cnt*BLK_SIZE); buf+=cnt*BLK_SIZE; blk+=cnt; } } f->fblk_num=blk; disk_status_display.u2[1]=0; return TRUE; } BoolU4 FWBlks(LTFile *f,U1 *buf,U8 blk=LTFB_NEXT_BLK,U8 cnt=1) { LTPartition *p=f->p; U8 spc=p->spc,i,j,c=f->de.cluster,c1; if (!f || !p) return FALSE; if (blk==LTFB_NEXT_BLK) blk=f->fblk_num; if (blk+cnt-1>f->max_blk) return FALSE; if (!(f->flags & LTF_WRITE)) return FALSE; if (!cnt) return TRUE; disk_status_display.u2[1]=0x8000+cnt/spc; if (f->flags & LTF_CONTIGUOUS) { WBlks(p,buf,ClusterBlk(p,c)+blk,cnt,TRUE); blk+=cnt; } else { if (!c) { c=AllocClusters(p,0,1,FALSE,TRUE); f->file_cluster_num=0; f->cluster=c; f->de.cluster=c; f->flags|=LTF_NEEDS_WRITE|LTF_NEW_FILE; } i=blk/spc; if (i>=f->file_cluster_num) { c=f->cluster; i-=f->file_cluster_num; } while (i) { c1=c; c=NextClusterNum(p,c1,1,TRUE); if (c==INVALID_CLUSTER) { c=AllocClusters(p,c1,i,FALSE,TRUE); if (i>1) c=NextClusterNum(p,c,i-1,TRUE); break; } else i--; } i=blk%spc; if (i) { FSetCluster(f,c,blk,TRUE); j=(cntcluster_buf+BLK_SIZE*i,buf,j*BLK_SIZE); f->flags|=LTF_BUF_DIRTY; buf+=j*BLK_SIZE; cnt-=j; blk+=j; if (cnt) { c1=c; c=NextClusterNum(p,c1,1,TRUE); if (c==INVALID_CLUSTER) c=AllocClusters(p,c1,1,FALSE,TRUE); } } while (cnt>=spc) { FSetCluster(f,c,blk,FALSE); MemCpy(f->cluster_buf,buf,spc*BLK_SIZE); f->flags|=LTF_BUF_DIRTY; buf+=spc*BLK_SIZE; cnt-=spc; blk+=spc; if (cnt) { c1=c; c=NextClusterNum(p,c1,1,TRUE); if (c==INVALID_CLUSTER) c=AllocClusters(p,c1,1,FALSE,TRUE); } } if (cnt) { FSetCluster(f,c,blk,TRUE); MemCpy(f->cluster_buf,buf,cnt*BLK_SIZE); f->flags|=LTF_BUF_DIRTY; buf+=cnt*BLK_SIZE; blk+=cnt; } if (f->de.sizede.size=blk*BLK_SIZE; if (f->de.expanded_sizede.expanded_size=blk*BLK_SIZE; } f->fblk_num=blk; disk_status_display.u2[1]=0; return TRUE; } void SelectDefaultDrive() { I1 ch; LTPartition *p; if (!default_drive) AddDrives(FALSE); while (!default_drive) { cout "\r\nContinue Boot to Which Drive? "; p=DriveToPartition(SysGetChar); CrLf; if (!p || p->type!=PT_ISO9660 && p->type!=PT_LT) { coutln "Invalid Partition"; PartitionRep; } else { if (p->bdev->flags & LTBDF_REMOVABLE) { ch=p->drive; coutln "Insert Diskette in Drive ",ch; } default_drive=p->drive; } } default_partition=DriveToPartition(default_drive); Fs->cur_partition=-1; //Null screws-up cache Fs->cur_dir=NewString("/"); ChangeDisk(':'); } BoolU4 CopySingleZ(I1 *f1,I1 *f2) //Just one file { U1 *file_buf=NULL; U8 size,attr=0; LTDirEntry de; if (FindFile(f1,&de,FALSE,TRUE)) { file_buf=ReadFile(f1,&size,&attr); attr=FileAttr(f2,attr); if (file_buf) { coutln "Copying ",f1," to ",f2; WriteFile(f2,file_buf,size,de.datetime,attr); Free(file_buf); return TRUE; } else PutSysText("ST_FILE_NOT_FOUND"); } else PutSysText("ST_FILE_NOT_FOUND"); return FALSE; } #define COPY_BUF_BLKS 0x400 BoolU4 CopySingle(I1 *f1,I1 *f2) //Just one file { U1 *buf; U8 cnt,l,size,attr1=FileAttr(f1),attr2=FileAttr(f2); LTFile *in_file=NULL,*out_file=NULL; U8 xsum=LT_XSUM,i,j; if (!StrCmp(f1,f2)) return FALSE; if (attr1!=attr2) return CopySingleZ(f1,f2); buf=MAlloc(COPY_BUF_BLKS*BLK_SIZE); if (attr2 & LT_ATTR_CONTIGUOUS) in_file=FOpen(f1,"rc"); else in_file=FOpen(f1,"r"); if (in_file) { size=FSize(in_file); cnt=(size+BLK_SIZE-1)/BLK_SIZE; if (attr2 & LT_ATTR_CONTIGUOUS) out_file=FOpen(f2,"wc",cnt); else out_file=FOpen(f2,"w",cnt); if (out_file) { coutln "Copying ",f1," to ",f2; j=size; while (cnt) { if (cnt>COPY_BUF_BLKS) { l=COPY_BUF_BLKS; i=l*BLK_SIZE; } else { l=cnt; i=j; } FRBlks(in_file, buf,LTFB_NEXT_BLK,l); xsum^=ArcCheckSum(buf,i); FWBlks(out_file,buf,LTFB_NEXT_BLK,l); cnt-=l; j-=l*BLK_SIZE; } if (in_file->de.xsum && in_file->de.xsum!=xsum) throw(EXCEPT_ARC_XSUM); out_file->de.xsum=xsum; out_file->flags|=LTF_USE_OLD_DATETIME; out_file->de.datetime=in_file->de.datetime; out_file->de.size=size; out_file->de.expanded_size=in_file->de.expanded_size; out_file->de.attr=FileAttr(f2,in_file->de.attr); FClose(out_file); FClose(in_file); Free(buf); return TRUE; } else PutSysText("ST_FILE_NOT_FOUND"); FClose(in_file); } else PutSysText("ST_FILE_NOT_FOUND"); Free(buf); return FALSE; } BoolU4 MkDir(I1 *filename) { U8 c,size,cur_dir_cluster; U1 *buf; BoolU4 result=FALSE; LTDirEntry *dLT; I1 *name; if (FindFile(filename,NULL,TRUE)) return FALSE; LTFileAccess *fa=NewLTFileAccess(filename); if (fa) { if (!CheckFileName(fa->mask)) PutSysText("ST_INVALID_FILENAME"); else { name=MStringUtil(fa->mask, SU_REMOVE_LEADING|SU_REMOVE_TRAILING| SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS); size=fa->p->spc*BLK_SIZE; buf=MAllocZ(size); cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE); if (fa->p->type==PT_LT) { dLT=buf-offset(LTDirEntry.start); c=WriteFile(name,buf,size,0,LT_ATTR_DIR,FALSE); dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS; StrCpy(dLT->name,name); dLT->cluster=c; dLT->size=size; dLT->expanded_size=size; dLT->datetime=GetCurTimeLTDate; dLT+=LT_DIR_ENTRY_SIZE; dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS; dLT->name[0]='.'; dLT->name[1]='.'; dLT->name[2]=0; dLT->cluster=cur_dir_cluster; dLT->size=0; dLT->expanded_size=0; dLT->datetime=GetCurTimeLTDate; } WClusters(fa->p,buf,c,1,TRUE); Free(buf); Free(name); result=TRUE; } DelLTFileAccess(fa); } return result; } void SysDel(I1 *wild,BoolU4 make_mask) //this is dangerous { LTFileAccess *fa=NewLTFileAccess(wild,make_mask); if (fa) { if (fa->p->type==PT_LT) DelLTFiles(fa->p,Fs->cur_dir,fa->mask,TRUE); DelLTFileAccess(fa); } } void Format(I8 drive_letter,BoolU4 quick=TRUE,BoolU4 confirm=TRUE,U8 type=PT_LT) { LTPartition *p=DriveToPartition(drive_letter); if (confirm) { cout "Are you sure "; if (!YorN) return; } if (!p) { PutSysText("ST_INVALID_DRIVE"); return; } if (type==PT_LT) { Drive(drive_letter); FormatLT(drive_letter,quick); InvalidateDiskCache(DriveToPartition(drive_letter),TRUE); Drive(drive_letter); } } void ReadCDImage(I1 drive,I1 *out_name) { LTBlkDev *bdev=DriveToBlkDev(drive); LTPartition *p=DriveToPartition(drive); U1 *buf=MAlloc(COPY_BUF_BLKS*BLK_SIZE); I1 *out_name2=DefaultExtension(out_name,"ISO"); LTFile *f=FOpen(out_name2,"w"); U8 l,dv,blk=0,cnt; InitBlkDev(bdev,TRUE); if (bdev->type!=LTBDT_ATAPI) throw(EXCEPT_BLKDEV,3); dv=bdev->blk_size/BLK_SIZE; cnt=((p->size+dv-1)/dv)*dv; while (cnt) { if (cnt>COPY_BUF_BLKS) l=COPY_BUF_BLKS; else l=cnt; if (l>bdev->max_reads) l=bdev->max_reads; if (!Bt(&sys_flags,SYSf_NO_IO_SOUND)) Sound(bdev->read_freq); disk_status_display.u2[1]=cnt/l; disk_status_display.u2[0]=l/dv; ATAPIReadBlks2(bdev,buf,blk/dv,l/dv); disk_status_display=0; if (!Bt(&sys_flags,SYSf_NO_IO_SOUND)) Sound(0); FWBlks(f,buf,blk,l); cnt-=l; blk+=l; } FClose(f); Free(buf); Free(out_name2); } class LTDuelBuf { U1 *buf0,*buf1; U8 in_buf,out_buf,cnt; I1 *filename; LTBlkDev *CD_bdev; }; void WriteCDImageTsk() { LTDuelBuf *d=Fs->user_aux1; U1 *buf; U8 l,blk=0,cnt=d->cnt; LTFile *f; if (FileAttr(d->filename)<_ATTR_CONTIGUOUS) f=FOpen(d->filename,"rc"); else f=FOpen(d->filename,"r"); while (cnt) { if (cnt>COPY_BUF_BLKS) l=COPY_BUF_BLKS; else l=cnt; if (l>d->CD_bdev->max_writes) l=d->CD_bdev->max_writes; buf=(d->in_buf & 1) ? d->buf1:d->buf0; while (d->in_buf>d->out_buf+1) SwapInNext; FRBlks(f,buf,blk,l); if (!Bt(&sys_flags,SYSf_NO_IO_SOUND)) Sound(d->CD_bdev->write_freq); d->in_buf++; cnt-=l; blk+=l; } FClose(f); } void WriteCDImage(I1 drive,I1 *in_name) { LTDuelBuf *d=MAllocZ(sizeof(LTDuelBuf)); U1 *buf; I1 *in_name3=DefaultExtension(in_name,"ISO"); I1 *in_name2=AbsoluteFileName(in_name3); U8 l,dv,blk=0,cnt; LTPartition *p=DriveToPartition(drive); LTBlkDev *bdev=p->bdev; TssStruct *tss; BoolU4 old_preempt; LTFile *f=FOpen(in_name2,"r"); if (!f) { Free(d); return; } cnt=(FSize(f)+BLK_SIZE-1)/BLK_SIZE; FClose(f); if (bdev->type!=LTBDT_ATAPI) throw(EXCEPT_BLKDEV,4); bdev->flags|=LTBDF_READ_ONLY_OVERRIDE; InitBlkDev(bdev,TRUE); dv=bdev->blk_size/BLK_SIZE; if (p->sizesize=cnt; d->filename=in_name2; d->CD_bdev=bdev; d->buf0=MAlloc(COPY_BUF_BLKS*BLK_SIZE); d->buf1=MAlloc(COPY_BUF_BLKS*BLK_SIZE); d->cnt=cnt; old_preempt=Preempt(OFF); tss=Spawn(&WriteCDImageTsk,"WRITE CD"); tss->user_aux1=d; Preempt(old_preempt); while (d->in_buf<=d->out_buf) SwapInNext; if (!Bt(&sys_flags,SYSf_NO_IO_SOUND)) Sound(bdev->write_freq); IDEWaitForDrive(bdev); ATAPIWaitReady(bdev); while (cnt) { if (cnt>COPY_BUF_BLKS) l=COPY_BUF_BLKS; else l=cnt; if (l>bdev->max_writes) l=bdev->max_writes; buf=(d->out_buf&1) ? d->buf1:d->buf0; while (d->in_buf<=d->out_buf) SwapInNext; disk_status_display.u2[1]=cnt/l+0x8000; disk_status_display.u2[0]=l/dv+0x8000; ATAPIWriteBlks(bdev,buf,blk/dv,(l+dv-1)/dv); disk_status_display=0; d->out_buf++; cnt-=l; blk+=l; } ATAPISync(bdev); ATAPIClose(bdev); if (!Bt(&sys_flags,SYSf_NO_IO_SOUND)) Sound(0); bdev->flags&=~LTBDF_READ_ONLY_OVERRIDE; Btr(&sys_irq_busy_flags,bdev->irq); Free(d->buf0); Free(d->buf1); Free(d); Free(in_name2); Free(in_name3); }