Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "common.h"
- #include "mm.h"
- #include "fat.h"
- #include "iodev.h"
- #include "process.h"
- static void *fat12_load_file(fat_t* fat, uint16 cluster, uint32 size);
- static void fat12_read_cluster(fat_t* fat, uint16 cluster, uint32 buffer);
- static dir_entry_t* fat12_src_filename(fat_t* fat, uint16 cluster, uint8* fn, uint8* ext);
- static uint32 fat12_get_cluster_sector(fat_t* fat,uint16 cluster);
- static uint16 fat12_get_next_cluster(fat_t* fat,uint16 cluster);
- fat_t* init_fat(block_device_t* dev){
- uint32 i,off;
- fat_t *ret = kmalloc(sizeof(fat_t));
- fat_BS_t* fat_bs = kmalloc(sizeof(fat_BS_t));
- char bs_buff[512]; /*Buffer gia boot sector kai FAT */
- memset(bs_buff,0,512); /*Nullify */
- ret->dev = dev;
- ret->bs = fat_bs; /*to boot sector */
- ret->dev->read_dev(0,ret->dev->attr,(uint32)&bs_buff); /*diavazoume to boot sector */
- memcpy((char*)fat_bs, bs_buff, sizeof(fat_BS_t)); /*sozoume sto FAT struct mas*/
- /*Upologisoume merikes times gia to filesystem mas */
- ret->root_dir_sectors = ((fat_bs->root_entry_count * 32) + (fat_bs->bytes_per_sector - 1)) / fat_bs->bytes_per_sector;
- ret->first_data_sector = fat_bs->reserved_sector_count + (fat_bs->table_count * fat_bs->table_size_16);
- ret->first_fat_sector = fat_bs->reserved_sector_count;
- ret->data_sectors = fat_bs->total_sectors_16 - (fat_bs->reserved_sector_count + (fat_bs->table_count * fat_bs->table_size_16) + ret->root_dir_sectors);
- ret->total_clusters = ret->data_sectors / fat_bs->sectors_per_cluster;
- ret->first_data_cluster_sect = ret->first_data_sector + ret->root_dir_sectors +1; /*To 1o sector meta to root dir */
- if(ret->total_clusters < 4085) {
- /* fat_type = 12; */
- ret->type = 12;
- ret->root_dir = ret->first_data_sector; /*to 1o sector isoute me to sector tou root dir */
- ret->FAT = kmalloc(512*((ret->first_data_sector)/2)); /*alloc gia to FAT */
- memset((char*)ret->FAT,0, 512*((ret->first_data_sector)/2)); /*nullify */
- off = 0; /*tmp offset */
- for (i = 1; i < (ret->first_data_sector+1)/2 ; i++){
- ret->dev->read_dev(i,ret->dev->attr,(uint32)bs_buff); /*Diavazoume ta sectors tou FAT */
- memcpy((char*)ret->FAT +off,bs_buff,512); /*Ta grafoume sto cache mas */
- off += 0x200; /*Fix to offset */
- putch('.'); /*progress */
- }
- ret->root_nd = kmalloc(sizeof(vfs_node_t));
- memset((char*)ret->root_nd, 0 , sizeof(vfs_node_t));
- strcpy(ret->root_nd->filename, "fat_root");
- ret->root_nd->fs_instance = ret;
- ret->root_nd->mask = 0xFFFFFFFF; /*Future use permisions */
- ret->root_nd->uid = 0; /*Future use */
- ret->root_nd->gid = 0; /*Future use */
- ret->root_nd->flags = FS_DIRECTORY;
- ret->root_nd->inode = 2; /*Cluster */
- ret->root_nd->size = 0;
- ret->root_nd->is_head = 1;
- /*Ta routines */
- ret->root_nd->read = &fat_vfs_read;
- ret->root_nd->write = 0;
- ret->root_nd->open = &open; /*apo vfs.c */
- ret->root_nd->close = &close; /*apo vfs.c */
- // ret->root_nd->readdir = &fat_vfs_readdir;
- ret->root_nd->readdir = &readdir;/*apo vfs.c */
- ret->root_nd->finddir = &finddir;/*apo vfs.c */
- ret->root_nd->expanddir = &fat_vfs_expanddir;
- ret->root_nd->ptr = 0;
- ret->root_nd->next = 0;
- return ret; /*Eimaste etimoi */
- }
- else {
- if(ret->total_clusters < 65525) {
- /* fat_type = 16; */
- ret->type = 16;
- ret->root_dir = ret->first_data_sector;
- }
- else {
- /* fat_type = 32; */
- ret->type = 32;
- ret->root_dir = ((fat_extBS_32_t*)(ret->bs->extended_section))->root_cluster;
- }
- }
- return ret;
- }
- vfs_node_t* fat_vfs_expanddir(vfs_node_t* nd){
- fat_t* fat = nd->fs_instance;
- uint16 cluster = (uint16)nd->inode;
- uint32 j;
- dir_entry_t *i;
- vfs_node_t *ret,*buff,*prv;
- dir_entry_t **tmp,*dent;
- char fbuff[9], ebuff[4],*c;
- ret = kmalloc(sizeof(vfs_node_t));
- memset((char*)ret,0,sizeof(vfs_node_t));
- /*Set to node */
- strcpy(ret->filename, nd->filename);
- ret->fs_instance = fat;
- ret->mask = 0xFFFFFFFF; /*Future use permisions */
- ret->uid = 0; /*Future use */
- ret->gid = 0; /*Future use */
- ret->flags = FS_DIRECTORY;
- ret->inode = cluster; /*Cluster */
- ret->size = 0;
- ret->is_head = 1;
- /*Ta routines */
- ret->read = &fat_vfs_read;
- ret->write = 0;
- ret->open = &open; /*apo vfs.c */
- ret->close = &close; /*apo vfs.c */
- // ret->readdir = &fat_vfs_readdir;
- ret->readdir = &readdir;/*apo vfs.c */
- ret->finddir = &finddir;/*apo vfs.c */
- ret->expanddir = &fat_vfs_expanddir;
- ret->ptr = 0;
- ret->next = 0;
- prv = ret;
- tmp = fat_expand_dir(fat,cluster);
- for (j = 0; tmp[j] != 0; j++){
- buff = kmalloc(sizeof(vfs_node_t));
- memset((char*)buff,0,sizeof(vfs_node_t));
- dent = tmp[j];
- memcpy(fbuff, dent->filename, 8);
- fbuff[8] = 0;
- memcpy(ebuff, dent->ext, 3);
- ebuff[3] = 0;
- for (c = fbuff; *c != ' ' && *c; c++);
- *c = 0;
- for (c = ebuff; *c != ' ' && *c; c++);
- *c = 0;
- strcpy(buff->filename,fbuff);
- if (strlen(ebuff)){
- strcat(buff->filename,".");
- strcat(buff->filename,ebuff);
- }
- buff->fs_instance = fat;
- buff->inode = dent->cluster;
- buff->mask = 0xFFFFFFFF;
- buff->uid = 0; /*Future use */
- buff->gid = 0; /*Future use */
- buff->is_head = 0;
- if (dent->attr == DIRECTORY)
- buff->flags = FS_DIRECTORY;
- else
- buff->flags = FS_FILE;
- buff->inode = dent->cluster;
- buff->size = dent->size;
- buff->read = &fat_vfs_read;
- buff->write = 0;
- buff->open = &open; /*apo vfs.c */
- buff->close = &close; /*apo vfs.c */
- // buff->readdir = &fat_vfs_readdir;
- buff->readdir = &readdir;/*apo vfs.c */
- buff->finddir = &finddir;/*apo vfs.c */
- buff->expanddir = &fat_vfs_expanddir;
- buff->ptr = 0;
- buff->next = 0 ;
- prv->next = buff;
- prv = buff;
- kfree(tmp[j]);
- }
- kfree(tmp);
- return ret;
- }
- uint32 fat_vfs_read(uint32 filedes, uint32 offset, uint32 size, uint8* buffer){
- proc_set_semaphore();
- file_descriptor_t* desc;
- char*file;
- desc = get_filedes(filedes);
- if ((offset + size) > desc->size) return -1; /*Kai ta dirs -1 */
- file = fat_load_file(desc->fs_instance,desc->inode,desc->size);
- memcpy((char*)buffer,(char*)((uint32)file + offset), size);
- buffer[size] = 0; /*end of file */
- kfree(file);
- proc_clear_semaphore();
- return 1;
- }
- void *fat_load_file(fat_t* fat, uint32 cluster, uint32 size){
- /*Apla epilegei to load routine analoga to type */
- if (fat->type == 12) /*FAT12 */
- return fat12_load_file(fat, (uint16)cluster, size);
- else if (fat->type == 16) {} /*FAT16 */
- else {} /*FAT32 */
- }
- static void *fat12_load_file(fat_t* fat, uint16 cluster, uint32 size){
- /*Alloc kai load file stin mnimi */
- void *tmp;
- char *c;
- uint32 ns;
- uint32 offset;
- ns = (size/(fat->bs->sectors_per_cluster*512)) + 1; /*Fix to size se sector bound */
- tmp = kmalloc(ns * (fat->bs->sectors_per_cluster * 512)); /*Alloc ta sectors */
- offset = 0; /*Offset son buffer */
- while(offset < size && cluster && cluster < 0xFF8 ){ /*< apo size, cluster !=0 kai < EOF */
- fat12_read_cluster(fat,cluster,(uint32)tmp + offset); /*Read to cluster sto buffer[offs] */
- offset += (uint32)fat->bs->sectors_per_cluster * 512; /*Fix to offset gia next sector */
- cluster = fat12_get_next_cluster(fat,cluster); /*Epomeno cluster sto chain */
- }
- offset -= (uint32)fat->bs->sectors_per_cluster * 512; /*Pame sto proigoumeno sector bound */
- c = tmp + offset; /*Panw ston buffer */
- c[size % (fat->bs->sectors_per_cluster * 512)] = 0x4; /*mark to telos tou file me EOF */
- return tmp;
- }
- dir_entry_t* fat_find_dir(fat_t* fat, char* path){
- uint32 i,cl = 2;
- char *c = path,buff[9],ebuff[4];
- char no_ext[] = " ";
- dir_entry_t *dent = 0;
- if (*c == '/') c++;
- while (*c){
- if (dent){
- kfree(dent);
- dent = 0;
- }
- for (i = 0; i < 8 && *c; i++){
- if (*c == '/') {c++; break;}
- if (*c == '.') break;
- buff[i] = *c++;
- }
- buff[i] = 0;
- if (*c == '.') {
- c++;
- for (i = 0; i < 3 && *c; i++){
- if (*c == '/') {c++; break;}
- ebuff[i] = *c++;
- }
- ebuff[3]=0;
- }
- else
- ebuff[0]=0;
- dent = fat12_src_filename(fat, cl, (uint8*)buff,(uint8*)ebuff);
- cl = dent->cluster;
- }
- return dent;
- }
- dir_entry_t** fat_expand_dir(fat_t* fat, uint32 cluster){
- char dir[512];
- uint8 *tmp,*c;
- dir_entry_t *dent; /*dir entry */
- dir_entry_t *array[512],**ret; /*buffer, mexri tosa entries return */
- uint32 i = 0;
- /*Ksekiname to browse tou katalogou */
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- while (1){
- if (tmp >= (uint8*)(dir + 512)){ /*Pera ap ta oria */
- if (cluster != 2){ /*oxi gia to root dir */
- cluster = fat12_get_next_cluster(fat, cluster); /*pame sto next cluster */
- if (cluster && cluster <= 0xFF8){ /*An yparxei .. */
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- }
- else { /*Allios return */
- goto rethere;
- }
- }
- }
- if (*tmp == 0) break; /*End of directory */
- if (*tmp == 0xE5) { /*Den xrisimopoieitai to entry */
- tmp += sizeof(dir_entry_t);
- continue;
- }
- if (*tmp == '.') { /*dor or dotdot entry */
- tmp += sizeof(dir_entry_t);
- continue;
- }
- if ((*tmp & 0xF0) == 0x40){ /*Long Directory enties */
- while ((*tmp & 0x0F) != 0x01){ /*Last Long dir Entry */
- tmp += sizeof(dir_long_t); /*next */
- /*Epidi exoume loop, psaxnoume ki edw min vgoume ap ta oria tou sect */
- if (tmp >= (uint8*)(dir + 512)){
- if (cluster != 2){
- cluster = fat12_get_next_cluster(fat, cluster);
- if (cluster && cluster <= 0xFF8){
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- }
- else {
- goto rethere;
- }
- }
- }
- }
- tmp += sizeof(dir_long_t); /*Telos prospername kai to last */
- }
- /*Kai kapou edw vriskomaste se pragmatiko Directory Entry */
- dent = (dir_entry_t*)tmp;
- array[i] = kmalloc(sizeof(dir_entry_t));
- memcpy((char*)array[i],(char*)dent,sizeof(dir_entry_t));
- i++;
- tmp += sizeof(dir_entry_t);
- }
- rethere:
- if (i == 0) return 0;
- ret = kmalloc((i+1)*sizeof(dir_entry_t));
- memcpy((char*)ret, (char*)array,i*sizeof(dir_entry_t));
- ret[i] = 0;
- return ret; /*Den vrikame tpt */
- }
- dirent_t* fat_vfs_readdir(struct vfs_node*nd, uint32 n){
- uint32 j;
- fat_t* fat = nd->fs_instance;
- uint16 cluster = (uint16)nd->inode;
- char buff[9], ebuff[4],*c;
- dirent_t *ret = 0;
- dir_entry_t **tmp,*dent;
- tmp = fat_expand_dir(fat,cluster);
- for (j = 0; tmp[j] != 0; j++){
- if (j == n){
- dent = tmp[j];
- memcpy(buff, dent->filename, 8);
- buff[8] = 0;
- memcpy(ebuff, dent->ext, 3);
- ebuff[3] = 0;
- for (c = buff; *c != ' ' && *c; c++);
- *c = 0;
- for (c = ebuff; *c != ' ' && *c; c++);
- *c = 0;
- ret = kmalloc(sizeof(dirent_t));
- strcpy(ret->filename,buff);
- if (strlen(ebuff)){
- strcat(ret->filename,".");
- strcat(ret->filename,ebuff);
- }
- ret->ino = dent->cluster;
- }
- kfree(tmp[j]);
- }
- kfree(tmp);
- return ret;
- }
- static dir_entry_t* fat12_src_filename(fat_t* fat, uint16 cluster, uint8* fn, uint8 *ext){
- char dir[512];
- char buff[9],ebuff[4];
- uint8 *tmp;
- dir_entry_t *dent,*ret; /*dir entry */
- dir_long_t *dlng; /*dir long entry */
- /*Convert se dir_entry->filename format */
- str_upper_case(fn); /*Upper case */
- for (tmp = fn; *tmp; tmp++); /*sto end of string */
- for (; tmp < fn+9; tmp++)*tmp = ' '; /*oti menei spaces */
- fn[8] = 0; /*end of string */
- /*Convert se dir_entry->ext format */
- str_upper_case(ext); /*Upper case */
- for (tmp = ext; *tmp; tmp++); /*sto end of string */
- for (; tmp < ext+4; tmp++)*tmp = ' '; /*oti menei spaces */
- ext[3] = 0; /*end of string */
- /*Ksekiname to browse tou katalogou */
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- while (1){
- if (tmp >= (uint8*)(dir + 512)){ /*Pera ap ta oria */
- if (cluster != 2){ /*oxi gia to root dir */
- cluster = fat12_get_next_cluster(fat, cluster); /*pame sto next cluster */
- if (cluster && cluster <= 0xFF8){ /*An yparxei .. */
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- }
- else /*Allios return */
- return 0;
- }
- }
- if (*tmp == 0) break; /*End of directory */
- if (*tmp == 0xE5) { /*Den xrisimopoieitai to entry */
- tmp += sizeof(dir_entry_t);
- continue;
- }
- if (*tmp == '.') { /*dor or dotdot entry */
- tmp += sizeof(dir_entry_t);
- continue;
- }
- if ((*tmp & 0xF0) == 0x40){ /*Long Directory enties */
- while ((*tmp & 0x0F) != 0x01){ /*Last Long dir Entry */
- tmp += sizeof(dir_long_t); /*next */
- /*Epidi exoume loop, psaxnoume ki edw min vgoume ap ta oria tou sect */
- if (tmp >= (uint8*)(dir + 512)){
- if (cluster != 2){
- cluster = fat12_get_next_cluster(fat, cluster);
- if (cluster && cluster <= 0xFF8){
- fat12_read_cluster(fat,cluster,(uint32)dir);
- tmp = dir;
- }
- else
- return 0;
- }
- }
- }
- tmp += sizeof(dir_long_t); /*Telos prospername kai to last */
- }
- /*Kai kapou edw vriskomaste se pragmatiko Directory Entry */
- dent = (dir_entry_t*)tmp;
- memcpy(buff, dent->filename, 8);
- buff[9] = 0;
- memcpy(ebuff, dent->ext, 3);
- ebuff[3] = 0;
- if (strcmp(fn, buff) == 0 && strcmp(ext, ebuff) == 0){
- ret = kmalloc(sizeof(dir_entry_t));
- memcpy((char*)ret, (char*)dent, sizeof(dir_entry_t));
- return ret; /*Vrikame to entry, ret */
- }
- tmp += sizeof(dir_entry_t);
- }
- return 0; /*Den vrikame tpt */
- }
- static void fat12_read_cluster(fat_t* fat,uint16 cluster, uint32 buffer){
- /*Diavazei ena cluster kai to sozei ston buffer */
- uint32 sect,i;
- char *p = (char*)buffer;
- sect = fat12_get_cluster_sector(fat,cluster);
- for (i = 0; i < fat->bs->sectors_per_cluster; i++) /*An to cluster exei panw apo 1 sector */
- fat->dev->read_dev(sect+i,fat->dev->attr,(uint32)(&p[512*i]));
- }
- static uint32 fat12_get_cluster_sector(fat_t* fat,uint16 cluster){
- /*Mas dinei to Sector opou vriskete ena cluster, gia na to diavasoume */
- if (cluster >=3)
- return (fat->first_data_cluster_sect + ((cluster-3)*fat->bs->sectors_per_cluster));
- return fat->first_data_sector; /*Cluster 2 */
- }
- static uint16 fat12_get_next_cluster(fat_t* fat,uint16 cluster){
- /*Psaxnei sto FAT kai mas epistrefei to Next Cluster tou chain */
- uint32 fat_offset = cluster + (cluster / 2) ; /* Polaplasiasmos *1,5 (efoson einai 12 bit per addr */
- void* tmp = &fat->FAT[fat_offset]; /* Pigenoume sto offset panw sto FAT */
- uint16 table_value; /* Tha parei to value */
- uint32 val = (*(uint32*)tmp) & 0x0000FFFF; /*pernoume 3 bytes */
- uint32 t = (*(uint32*)tmp);
- if(cluster & 0x0001){ /*Mono cluster */
- table_value = (uint16)(val >> 4); /*Pernei to word Shifted 4 bits */
- }
- else /*Zigo cluster */
- table_value = (uint16)(val & 0x0FFF); /*Pernei to address opos einai */
- return table_value;
- }
Add Comment
Please, Sign In to add comment