/* **************************************************************************** * void dir_createDirectoryEntry(FileSystem *fs,FileRecord *filerec,FileLocation *loc) * Description: This function writes the filerecord stored in filerec to disc at * location loc. * Return value: void */ void dir_createDirectoryEntry(FileSystem *fs,FileRecord *filerec,FileLocation *loc) { euint8 *buf; buf = part_getSect(fs->part,loc->Sector,IOM_MODE_READWRITE); memCpy(filerec,buf+(loc->Offset*sizeof(*filerec)),sizeof(*filerec)); part_relSect(fs->part,buf); }
/* **************************************************************************** * void dir_setFileSize(FileSystem *fs, FileLocation *loc,euint32 numbytes) * Description: This function changes the filesize recorded at loc->Sector * to 'numbytes'. * Return value: void */ void dir_setFileSize(FileSystem *fs, FileLocation *loc,euint32 numbytes) { euint8 *buf; buf = part_getSect(fs->part,loc->Sector,IOM_MODE_READWRITE); (((FileRecord*)buf)+loc->Offset)->FileSize=numbytes; part_relSect(fs->part,buf); }
/* **************************************************************************** * void dir_getFileStructure(FileSystem *fs,FileRecord *filerec,FileLocation *loc) * Description: This function stores the filerecord located at loc in filerec. * It fetches the required sector for this. * Return value: void */ void dir_getFileStructure(FileSystem *fs,FileRecord *filerec,FileLocation *loc) { euint8 *buf; buf=part_getSect(fs->part,loc->Sector,IOM_MODE_READONLY); *filerec=*(((FileRecord*)buf)+loc->Offset); part_relSect(fs->part,buf); }
/* **************************************************************************** * esint8 dir_updateDirectoryEntry(FileSystem *fs,FileRecord *entry,FileLocation *loc)) * This function changes the entire entity stores at loc to the data recorded * in entry. This is for custom updates to the directoryentry. * Return value: 0 on success, -1 on failure */ esint8 dir_updateDirectoryEntry(FileSystem *fs,FileRecord *entry,FileLocation *loc) { euint8 *buf; buf = part_getSect(fs->part,loc->Sector,IOM_MODE_READWRITE); memCpy(entry,buf+(loc->Offset*sizeof(*entry)),sizeof(*entry)); part_relSect(fs->part,buf); return(0); }
/* **************************************************************************** * void dir_setFirstCluster(File *file,euint32 cluster_addr) * Description: This function requires modification to release it from * depending on the file object. * Return value: */ void dir_setFirstCluster(FileSystem *fs,FileLocation *loc,euint32 cluster_addr) { euint8 *buf; buf = part_getSect(fs->part,loc->Sector,IOM_MODE_READWRITE); (((FileRecord*)buf)+loc->Offset)->FirstClusterHigh=cluster_addr>>16; (((FileRecord*)buf)+loc->Offset)->FirstClusterLow=cluster_addr&0xFFFF; part_relSect(fs->part,buf); }
/* **************************************************************************** * euint32 file_fread(File *file,euint32 offset, euint32 size,euint8 *buf) * Description: This function reads 'size' bytes from 'file' starting at * 'offset' and puts the result in '*buf'. * Return value: amount of bytes actually read (can differ from the given * size when the file was smaller */ euint32 file_fread(File *file,euint32 offset, euint32 size,euint8 *buf) { //OSTaskSuspend(1); euint32 bytes_read=0,size_left=size,coffset=offset; euint32 cclus,csec,cbyte; euint32 rclus,rsec; euint32 btr; euint8 *tbuf; if(!file_getAttr(file,FILE_STATUS_OPEN))return(0); if(offset>=file->FileSize) size_left=0; /* Offset check */ if( (offset+size > file->FileSize) && size_left!=0) size_left=file->FileSize-offset; while(size_left>0){ //printf("size_left = %d\n", size_left); cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster); csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster; cbyte = coffset%512; if(cbyte!=0 || size_left<512){ btr = 512-(coffset%512)>=size_left?size_left:512-(coffset%512); }else{ btr = 512; } if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){ return(0); } rclus=file->Cache.DiscCluster; rsec=fs_clusterToSector(file->fs,rclus); if(btr==512){ /*part_readBuf(file->fs->part,rsec+csec,buf+bytes_read);*/ part_directSectorRead(file->fs->part,rsec+csec,buf+bytes_read); }else{ /*part_readBuf(file->fs->part,rsec+csec,tbuf);*/ tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READONLY); memCpy(tbuf+(coffset%512),buf+bytes_read,btr); part_relSect(file->fs->part,tbuf); } coffset+=btr; bytes_read+=btr; size_left-=btr; } //OSTaskResume(1); return(bytes_read); }
/* **************************************************************************** * eint16 fs_isValidFat(Partition *part) * Description: This functions loads the volumeID and checks if the magic * value is present. * Return value: returns 0 when magic code is missing, 1 if it is there. */ eint16 fs_isValidFat(Partition *part) { euint8 *buf; buf=part_getSect(part,0,IOM_MODE_READONLY|IOM_MODE_EXP_REQ); /* Load Volume label */ if( ex_getb16(buf,0x1FE) != 0xAA55 ){ return (0); } part_relSect(part,buf); return(1); }
/* **************************************************************************** * unsigned long file_fread(File *file,unsigned long offset, unsigned long size,unsigned char *buf) * Description: This function reads 'size' bytes from 'file' starting at * 'offset' and puts the result in '*buf'. * Return value: amount of bytes actually read (can differ from the given * size when the file was smaller */ unsigned long file_fread(File *file,unsigned long offset, unsigned long size,unsigned char *buf) { unsigned long bytes_read=0,size_left=size,coffset=offset; unsigned long cclus,csec,cbyte; unsigned long rclus,rsec; unsigned long btr; unsigned char *tbuf; if(!file_getAttr(file,FILE_STATUS_OPEN))return(0); if(offset>=file->FileSize) size_left=0; /* Offset check */ if( (offset+size > file->FileSize) && size_left!=0) size_left=file->FileSize-offset; while(size_left>0){ cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster); csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster; cbyte = coffset%512; if(cbyte!=0 || size_left<512){ btr = 512-(coffset%512)>=size_left?size_left:512-(coffset%512); }else{ btr = 512; } if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){ return(0); } rclus=file->Cache.DiscCluster; rsec=fs_clusterToSector(file->fs,rclus); if(btr==512){ /*part_readBuf(file->fs->part,rsec+csec,buf+bytes_read);*/ part_directSectorRead(file->fs->part,rsec+csec,buf+bytes_read); }else{ /*part_readBuf(file->fs->part,rsec+csec,tbuf);*/ tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READONLY); memCpy(tbuf+(coffset%512),buf+bytes_read,btr); part_relSect(file->fs->part,tbuf); } coffset+=btr; bytes_read+=btr; size_left-=btr; } return(bytes_read); }
esint8 ls_getRootAreaEntry(DirList *dlist) { euint8 *buf=0; if((dlist->fs->type != FAT12) && (dlist->fs->type != FAT16))return(-1); if(dlist->rEntry>=dlist->fs->volumeId.RootEntryCount)return(-1); buf = part_getSect(dlist->fs->part, dlist->fs->FirstSectorRootDir+dlist->rEntry/16, IOM_MODE_READONLY); /*memCpy(buf+32*(dlist->rEntry%16),&(dlist->currentEntry),32);*/ ls_fileEntryToDirListEntry(dlist,buf,32*(dlist->rEntry%16)); part_relSect(dlist->fs->part,buf); return(0); }
/* **************************************************************************** * euint32 dir_findinCluster(FileSystem *fs,euint32 cluster,eint8 *fatname, FileLocation *loc, euint8 mode) * This function will search for an existing (fatname) or free directory entry * in a full cluster. * Return value: 0 on failure, firstcluster on finding file, and 1 on finding free spot. */ euint32 dir_findinCluster(FileSystem *fs,euint32 cluster,eint8 *fatname, FileLocation *loc, euint8 mode) { euint8 c,*buf=0; euint32 fclus; for(c=0; c<fs->volumeId.SectorsPerCluster; c++) { buf = part_getSect(fs->part,fs_clusterToSector(fs,cluster)+c,IOM_MODE_READONLY); if((fclus=dir_findinBuf(buf,fatname,loc,mode))) { if(loc)loc->Sector=fs_clusterToSector(fs,cluster)+c; part_relSect(fs->part,buf); return(fclus); } } part_relSect(fs->part,buf); return(0); }
/* **************************************************************************** * euint32 dir_findinDir(FileSystem *fs, eint8* fatname,euint32 firstcluster, FileLocation *loc, euint8 mode) * This function will search for an existing (fatname) or free directory entry * in the rootdirectory-area of a FAT12/FAT16 filesystem. * Return value: 0 on failure, firstcluster on finding file, and 1 on finding free spot. */ euint32 dir_findinRootArea(FileSystem *fs,eint8* fatname, FileLocation *loc, euint8 mode) { euint32 c,fclus; euint8 *buf=0; if((fs->type != FAT12) && (fs->type != FAT16))return(0); for(c=fs->FirstSectorRootDir; c<(fs->FirstSectorRootDir+fs->volumeId.RootEntryCount/32); c++) { buf = part_getSect(fs->part,c,IOM_MODE_READONLY); if((fclus=dir_findinBuf(buf,fatname,loc,mode))) { if(loc)loc->Sector=c; part_relSect(fs->part,buf); return(fclus); } part_relSect(fs->part,buf); } part_relSect(fs->part,buf); return(0); }
/* **************************************************************************** * void fs_loadVolumeId(FileSystem *fs, Partition *part) * Description: This function loads all relevant fields from the volumeid. */ void fs_loadVolumeId(FileSystem *fs, Partition *part) { euint8 *buf; buf=part_getSect(part,0,IOM_MODE_READONLY|IOM_MODE_EXP_REQ); fs->volumeId.BytesPerSector=ex_getb16(buf,0x0B); fs->volumeId.SectorsPerCluster=*((eint8*)(buf+0x0D)); fs->volumeId.ReservedSectorCount=ex_getb16(buf,0x0E); fs->volumeId.NumberOfFats=*((eint8*)(buf+0x10)); fs->volumeId.RootEntryCount=ex_getb16(buf,0x11); fs->volumeId.SectorCount16=ex_getb16(buf,0x13); fs->volumeId.FatSectorCount16=ex_getb16(buf,0x16); fs->volumeId.SectorCount32=ex_getb32(buf,0x20); fs->volumeId.FatSectorCount32=ex_getb32(buf,0x24); fs->volumeId.RootCluster=ex_getb32(buf,0x2C); part_relSect(part,buf); }
esint8 ls_getRealDirEntry(DirList *dlist) { euint8* buf; if(dlist->Cache.FirstCluster<=1)return(-1); if(fat_LogicToDiscCluster(dlist->fs, &(dlist->Cache), (dlist->rEntry)/(16 * dlist->fs->volumeId.SectorsPerCluster))){ return(-1); } buf = part_getSect(dlist->fs->part, fs_clusterToSector(dlist->fs,dlist->Cache.DiscCluster) + (dlist->rEntry/16)%dlist->fs->volumeId.SectorsPerCluster, IOM_MODE_READONLY); /*memCpy(buf+(dlist->rEntry%16)*32,&(dlist->currentEntry),32);*/ ls_fileEntryToDirListEntry(dlist,buf,32*(dlist->rEntry%16)); part_relSect(dlist->fs->part,buf); return(0); }
/* **************************************************************************** * euint32 file_fwrite(File* file,euint32 offset,euint32 size,euint8* buf) * Description: This function writes to a file, at offset 'offset' and size 'size'. * It also updates the FileSize in the object, and discstructure. * Return value: Bytes actually written. */ euint32 file_fwrite(File* file,euint32 offset,euint32 size,euint8* buf) { euint32 need_cluster; euint32 cclus,csec,cbyte; euint32 size_left=size,bytes_written=0; euint32 rclus,rsec; euint32 coffset=offset; euint16 btr; euint8 *tbuf; if(!file_getAttr(file,FILE_STATUS_OPEN) || !file_getAttr(file,FILE_STATUS_WRITE))return(0); if(offset>file->FileSize){ offset=file->FileSize; } need_cluster = file_requiredCluster(file,offset,size); if(need_cluster){ if(fat_allocClusterChain(file->fs,&(file->Cache),need_cluster+CLUSTER_PREALLOC_FILE)!=0){ return(0); } } while(size_left>0){ cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster); csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster; cbyte = coffset%512; if(cbyte!=0 || size_left<512){ btr = 512-(coffset%512)>=size_left?size_left:512-(coffset%512); }else{ btr = 512; } if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){ file->FileSize+=bytes_written; dir_setFileSize(file->fs,&(file->Location),file->FileSize); return(bytes_written); } rclus=file->Cache.DiscCluster; rsec=fs_clusterToSector(file->fs,rclus); if(btr==512){ /*part_writeBuf(file->fs->part,rsec+csec,buf+bytes_written);*/ part_directSectorWrite(file->fs->part,rsec+csec,buf+bytes_written); }else{ /*part_readBuf(file->fs->part,rsec+csec,tbuf);*/ tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READWRITE); memCpy(buf+bytes_written,tbuf+(coffset%512),btr); /*part_writeBuf(file->fs->part,rsec+csec,tbuf);*/ part_relSect(file->fs->part,tbuf); } coffset+=btr; bytes_written+=btr; size_left-=btr; } if(bytes_written>file->FileSize-offset){ file->FileSize+=bytes_written-(file->FileSize-offset); } return(bytes_written); }