Guest User

Untitled

a guest
Jun 25th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.64 KB | None | 0 0
  1.  
  2. #include "common.h"
  3. #include "mm.h"
  4. #include "fat.h"
  5. #include "iodev.h"
  6. #include "process.h"
  7.  
  8. static void *fat12_load_file(fat_t* fat, uint16 cluster, uint32 size);
  9. static void fat12_read_cluster(fat_t* fat, uint16 cluster, uint32 buffer);
  10. static dir_entry_t* fat12_src_filename(fat_t* fat, uint16 cluster, uint8* fn, uint8* ext);
  11. static uint32 fat12_get_cluster_sector(fat_t* fat,uint16 cluster);
  12. static uint16 fat12_get_next_cluster(fat_t* fat,uint16 cluster);
  13.  
  14. fat_t* init_fat(block_device_t* dev){
  15.     uint32 i,off;
  16.     fat_t *ret = kmalloc(sizeof(fat_t));
  17.     fat_BS_t* fat_bs = kmalloc(sizeof(fat_BS_t));
  18.  
  19.     char bs_buff[512];  /*Buffer gia boot sector kai FAT */
  20.     memset(bs_buff,0,512);  /*Nullify */
  21.  
  22.     ret->dev = dev;
  23.     ret->bs = fat_bs;           /*to boot sector */
  24.  
  25.     ret->dev->read_dev(0,ret->dev->attr,(uint32)&bs_buff);  /*diavazoume to boot sector */
  26.  
  27.     memcpy((char*)fat_bs, bs_buff, sizeof(fat_BS_t));   /*sozoume sto FAT struct mas*/
  28.     /*Upologisoume merikes times gia to filesystem mas */
  29.     ret->root_dir_sectors = ((fat_bs->root_entry_count * 32) + (fat_bs->bytes_per_sector - 1)) / fat_bs->bytes_per_sector;
  30.     ret->first_data_sector = fat_bs->reserved_sector_count + (fat_bs->table_count * fat_bs->table_size_16);
  31.     ret->first_fat_sector = fat_bs->reserved_sector_count;
  32.     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);
  33.     ret->total_clusters = ret->data_sectors / fat_bs->sectors_per_cluster;
  34.     ret->first_data_cluster_sect = ret->first_data_sector + ret->root_dir_sectors +1;   /*To 1o sector meta to root dir */
  35.  
  36.     if(ret->total_clusters < 4085) {
  37.         /* fat_type = 12; */
  38.         ret->type = 12;
  39.         ret->root_dir = ret->first_data_sector; /*to 1o sector isoute me to sector tou root dir */
  40.         ret->FAT = kmalloc(512*((ret->first_data_sector)/2));   /*alloc gia to FAT */
  41.         memset((char*)ret->FAT,0, 512*((ret->first_data_sector)/2));    /*nullify */
  42.         off = 0;    /*tmp offset */
  43.         for (i = 1; i < (ret->first_data_sector+1)/2 ; i++){
  44.             ret->dev->read_dev(i,ret->dev->attr,(uint32)bs_buff);   /*Diavazoume ta sectors tou FAT */
  45.             memcpy((char*)ret->FAT +off,bs_buff,512);   /*Ta grafoume sto cache mas */
  46.             off += 0x200;                   /*Fix to offset */
  47.             putch('.');                 /*progress */
  48.         }
  49.  
  50.         ret->root_nd = kmalloc(sizeof(vfs_node_t));
  51.         memset((char*)ret->root_nd, 0 , sizeof(vfs_node_t));
  52.  
  53.         strcpy(ret->root_nd->filename, "fat_root");
  54.         ret->root_nd->fs_instance = ret;
  55.         ret->root_nd->mask = 0xFFFFFFFF;    /*Future use permisions */
  56.         ret->root_nd->uid = 0;  /*Future use */
  57.         ret->root_nd->gid = 0;  /*Future use */
  58.         ret->root_nd->flags = FS_DIRECTORY;
  59.         ret->root_nd->inode = 2;    /*Cluster */
  60.         ret->root_nd->size = 0;
  61.         ret->root_nd->is_head = 1;
  62.         /*Ta routines */
  63.         ret->root_nd->read = &fat_vfs_read;
  64.         ret->root_nd->write = 0;
  65.         ret->root_nd->open = &open; /*apo vfs.c */
  66.         ret->root_nd->close = &close;   /*apo vfs.c */
  67. //      ret->root_nd->readdir = &fat_vfs_readdir;
  68.         ret->root_nd->readdir = &readdir;/*apo vfs.c */
  69.         ret->root_nd->finddir = &finddir;/*apo vfs.c */
  70.         ret->root_nd->expanddir = &fat_vfs_expanddir;
  71.    
  72.         ret->root_nd->ptr = 0;
  73.         ret->root_nd->next = 0;
  74.        
  75.         return ret; /*Eimaste etimoi */
  76.     }
  77.     else {
  78.         if(ret->total_clusters < 65525) {
  79.             /* fat_type = 16; */
  80.             ret->type = 16;
  81.             ret->root_dir = ret->first_data_sector;
  82.         }
  83.         else {
  84.             /* fat_type = 32; */
  85.             ret->type = 32;
  86.             ret->root_dir = ((fat_extBS_32_t*)(ret->bs->extended_section))->root_cluster;
  87.         }
  88.     }
  89.  
  90.     return ret;
  91. }
  92.  
  93. vfs_node_t* fat_vfs_expanddir(vfs_node_t* nd){
  94.     fat_t* fat = nd->fs_instance;
  95.     uint16 cluster = (uint16)nd->inode;
  96.     uint32 j;
  97.     dir_entry_t *i;
  98.     vfs_node_t *ret,*buff,*prv;
  99.     dir_entry_t **tmp,*dent;
  100.     char fbuff[9], ebuff[4],*c;
  101.  
  102.     ret = kmalloc(sizeof(vfs_node_t));
  103.     memset((char*)ret,0,sizeof(vfs_node_t));
  104.     /*Set to node */
  105.     strcpy(ret->filename, nd->filename);
  106.  
  107.     ret->fs_instance = fat;
  108.     ret->mask = 0xFFFFFFFF; /*Future use permisions */
  109.     ret->uid = 0;   /*Future use */
  110.     ret->gid = 0;   /*Future use */
  111.     ret->flags = FS_DIRECTORY;
  112.     ret->inode = cluster;   /*Cluster */
  113.     ret->size = 0;
  114.     ret->is_head = 1;
  115.     /*Ta routines */
  116.     ret->read = &fat_vfs_read;
  117.     ret->write = 0;
  118.     ret->open = &open;  /*apo vfs.c */
  119.     ret->close = &close;    /*apo vfs.c */
  120. //  ret->readdir = &fat_vfs_readdir;
  121.     ret->readdir = &readdir;/*apo vfs.c */
  122.     ret->finddir = &finddir;/*apo vfs.c */
  123.     ret->expanddir = &fat_vfs_expanddir;
  124.  
  125.     ret->ptr = 0;
  126.     ret->next = 0;
  127.  
  128.     prv = ret;
  129.  
  130.     tmp = fat_expand_dir(fat,cluster);
  131.  
  132.     for (j = 0; tmp[j] != 0; j++){
  133.         buff = kmalloc(sizeof(vfs_node_t));
  134.         memset((char*)buff,0,sizeof(vfs_node_t));
  135.  
  136.         dent = tmp[j];
  137.         memcpy(fbuff, dent->filename, 8);
  138.         fbuff[8] = 0;
  139.         memcpy(ebuff, dent->ext, 3);
  140.         ebuff[3] = 0;
  141.  
  142.         for (c = fbuff; *c != ' ' && *c; c++);
  143.         *c = 0;
  144.         for (c = ebuff; *c != ' ' && *c; c++);
  145.         *c = 0;
  146.         strcpy(buff->filename,fbuff);
  147.         if (strlen(ebuff)){
  148.             strcat(buff->filename,".");
  149.             strcat(buff->filename,ebuff);
  150.         }
  151.  
  152.         buff->fs_instance = fat;
  153.         buff->inode = dent->cluster;
  154.         buff->mask = 0xFFFFFFFF;
  155.         buff->uid = 0;  /*Future use */
  156.         buff->gid = 0;  /*Future use */
  157.         buff->is_head = 0;
  158.         if (dent->attr == DIRECTORY)
  159.             buff->flags = FS_DIRECTORY;
  160.         else
  161.             buff->flags = FS_FILE;
  162.         buff->inode = dent->cluster;
  163.  
  164.         buff->size = dent->size;
  165.         buff->read = &fat_vfs_read;
  166.         buff->write = 0;
  167.         buff->open = &open; /*apo vfs.c */
  168.         buff->close = &close;   /*apo vfs.c */
  169. //      buff->readdir = &fat_vfs_readdir;
  170.         buff->readdir = &readdir;/*apo vfs.c */
  171.         buff->finddir = &finddir;/*apo vfs.c */
  172.         buff->expanddir = &fat_vfs_expanddir;
  173.         buff->ptr = 0;
  174.         buff->next = 0 ;
  175.  
  176.         prv->next = buff;
  177.         prv = buff;
  178.  
  179.         kfree(tmp[j]);
  180.     }
  181.     kfree(tmp);
  182.     return ret;
  183. }
  184.  
  185. uint32  fat_vfs_read(uint32 filedes, uint32 offset, uint32 size, uint8* buffer){
  186.     proc_set_semaphore();
  187.     file_descriptor_t* desc;
  188.     char*file;
  189.     desc = get_filedes(filedes);
  190.     if ((offset + size) > desc->size) return -1;    /*Kai ta dirs -1 */
  191.     file = fat_load_file(desc->fs_instance,desc->inode,desc->size);
  192.  
  193.     memcpy((char*)buffer,(char*)((uint32)file + offset), size);
  194.  
  195.     buffer[size] = 0;   /*end of file */
  196.     kfree(file);
  197.  
  198.     proc_clear_semaphore();
  199.     return 1;
  200. }
  201.  
  202. void *fat_load_file(fat_t* fat, uint32 cluster, uint32 size){
  203. /*Apla epilegei to load routine analoga to type */
  204.     if (fat->type == 12) /*FAT12 */
  205.         return fat12_load_file(fat, (uint16)cluster, size);
  206.     else if (fat->type == 16) {} /*FAT16 */
  207.     else {} /*FAT32 */
  208. }
  209.  
  210. static void *fat12_load_file(fat_t* fat, uint16 cluster, uint32 size){
  211. /*Alloc kai load file stin mnimi */
  212.     void *tmp;
  213.     char *c;
  214.     uint32 ns; 
  215.     uint32 offset;
  216.  
  217.     ns = (size/(fat->bs->sectors_per_cluster*512)) + 1;     /*Fix to size se sector bound */
  218.     tmp = kmalloc(ns * (fat->bs->sectors_per_cluster * 512));   /*Alloc ta sectors */
  219.     offset = 0;                         /*Offset son buffer */
  220.     while(offset < size && cluster && cluster < 0xFF8 ){        /*< apo size, cluster !=0 kai < EOF */
  221.         fat12_read_cluster(fat,cluster,(uint32)tmp + offset);   /*Read to cluster sto buffer[offs] */
  222.         offset += (uint32)fat->bs->sectors_per_cluster * 512;   /*Fix to offset gia next sector */
  223.         cluster = fat12_get_next_cluster(fat,cluster);      /*Epomeno cluster sto chain */
  224.     }
  225.     offset -= (uint32)fat->bs->sectors_per_cluster * 512;       /*Pame sto proigoumeno sector bound  */
  226.     c = tmp + offset;                       /*Panw ston buffer */
  227.     c[size % (fat->bs->sectors_per_cluster * 512)] = 0x4;       /*mark to telos tou file me EOF */
  228.     return tmp;
  229. }
  230.  
  231. dir_entry_t* fat_find_dir(fat_t* fat, char* path){
  232.     uint32 i,cl = 2;
  233.     char *c = path,buff[9],ebuff[4];
  234.     char no_ext[] = "   ";
  235.     dir_entry_t *dent = 0;
  236.     if (*c == '/') c++;
  237.     while (*c){
  238.         if (dent){
  239.             kfree(dent);
  240.             dent = 0;
  241.         }
  242.         for (i = 0; i < 8 && *c; i++){
  243.             if (*c == '/') {c++; break;}
  244.             if (*c == '.') break;
  245.             buff[i] = *c++;
  246.         }
  247.         buff[i] = 0;
  248.         if (*c == '.') {
  249.             c++;
  250.             for (i = 0; i < 3 && *c; i++){
  251.                 if (*c == '/') {c++; break;}
  252.                 ebuff[i] = *c++;
  253.             }
  254.             ebuff[3]=0;
  255.         }
  256.         else
  257.             ebuff[0]=0;
  258.         dent = fat12_src_filename(fat, cl, (uint8*)buff,(uint8*)ebuff);
  259.         cl = dent->cluster;
  260.     }
  261.     return dent;
  262. }
  263.  
  264.  
  265. dir_entry_t** fat_expand_dir(fat_t* fat, uint32 cluster){
  266.     char dir[512];
  267.     uint8 *tmp,*c;
  268.     dir_entry_t *dent;  /*dir entry */
  269.     dir_entry_t *array[512],**ret;  /*buffer, mexri tosa entries return */
  270.     uint32 i = 0;
  271.  
  272.     /*Ksekiname to browse tou katalogou */
  273.     fat12_read_cluster(fat,cluster,(uint32)dir);
  274.     tmp = dir;
  275.     while (1){
  276.         if (tmp >= (uint8*)(dir + 512)){    /*Pera ap ta oria */
  277.             if (cluster != 2){  /*oxi gia to root dir */
  278.                 cluster = fat12_get_next_cluster(fat, cluster); /*pame sto next cluster */
  279.                 if (cluster && cluster <= 0xFF8){   /*An yparxei .. */
  280.                     fat12_read_cluster(fat,cluster,(uint32)dir);
  281.                     tmp = dir;
  282.                 }
  283.                 else {                  /*Allios return */
  284.                     goto rethere;
  285.                 }
  286.             }
  287.         }
  288.         if (*tmp == 0) break;               /*End of directory */
  289.         if (*tmp == 0xE5) {             /*Den xrisimopoieitai to entry */
  290.             tmp += sizeof(dir_entry_t);
  291.             continue;
  292.         }
  293.         if (*tmp == '.') {              /*dor or dotdot entry */
  294.             tmp += sizeof(dir_entry_t);
  295.             continue;
  296.         }
  297.         if ((*tmp & 0xF0) == 0x40){     /*Long Directory enties */
  298.             while ((*tmp & 0x0F) != 0x01){  /*Last Long dir Entry */
  299.                 tmp += sizeof(dir_long_t);  /*next */
  300.                 /*Epidi exoume loop, psaxnoume ki edw min vgoume ap ta oria tou sect */
  301.                 if (tmp >= (uint8*)(dir + 512)){
  302.                     if (cluster != 2){
  303.                         cluster = fat12_get_next_cluster(fat, cluster);
  304.                         if (cluster && cluster <= 0xFF8){
  305.                             fat12_read_cluster(fat,cluster,(uint32)dir);
  306.                             tmp = dir;
  307.                         }
  308.                         else {
  309.                             goto rethere;
  310.                         }
  311.                     }
  312.                 }
  313.             }
  314.             tmp += sizeof(dir_long_t);  /*Telos prospername kai to last */
  315.         }
  316.         /*Kai kapou edw vriskomaste se pragmatiko Directory Entry */
  317.         dent = (dir_entry_t*)tmp;
  318.         array[i] = kmalloc(sizeof(dir_entry_t));
  319.         memcpy((char*)array[i],(char*)dent,sizeof(dir_entry_t));
  320.         i++;
  321.         tmp += sizeof(dir_entry_t);
  322.     }
  323. rethere:
  324.     if (i == 0) return 0;
  325.     ret = kmalloc((i+1)*sizeof(dir_entry_t));
  326.     memcpy((char*)ret, (char*)array,i*sizeof(dir_entry_t));
  327.     ret[i] = 0;
  328.    
  329.     return ret; /*Den vrikame tpt */
  330. }
  331.  
  332. dirent_t* fat_vfs_readdir(struct vfs_node*nd, uint32 n){
  333.     uint32 j;
  334.     fat_t* fat = nd->fs_instance;
  335.     uint16 cluster = (uint16)nd->inode;
  336.     char buff[9], ebuff[4],*c;
  337.     dirent_t *ret = 0;
  338.     dir_entry_t **tmp,*dent;
  339.  
  340.     tmp = fat_expand_dir(fat,cluster);
  341.     for (j = 0; tmp[j] != 0; j++){
  342.         if (j == n){
  343.             dent = tmp[j];
  344.             memcpy(buff, dent->filename, 8);
  345.             buff[8] = 0;
  346.             memcpy(ebuff, dent->ext, 3);
  347.             ebuff[3] = 0;
  348.             for (c = buff; *c != ' ' && *c; c++);
  349.             *c = 0;
  350.             for (c = ebuff; *c != ' ' && *c; c++);
  351.             *c = 0;
  352.             ret = kmalloc(sizeof(dirent_t));
  353.             strcpy(ret->filename,buff);
  354.             if (strlen(ebuff)){
  355.                 strcat(ret->filename,".");
  356.                 strcat(ret->filename,ebuff);
  357.             }
  358.             ret->ino = dent->cluster;
  359.         }
  360.         kfree(tmp[j]);
  361.     }
  362.     kfree(tmp);
  363.  
  364.     return ret;
  365. }
  366.  
  367. static dir_entry_t* fat12_src_filename(fat_t* fat, uint16 cluster, uint8* fn, uint8 *ext){
  368.     char dir[512];
  369.     char buff[9],ebuff[4];
  370.     uint8 *tmp;
  371.     dir_entry_t *dent,*ret; /*dir entry */
  372.     dir_long_t  *dlng;  /*dir long entry */
  373.     /*Convert se dir_entry->filename format */
  374.     str_upper_case(fn);         /*Upper case */
  375.     for (tmp = fn; *tmp; tmp++);        /*sto end of string */
  376.     for (; tmp < fn+9; tmp++)*tmp = ' ';    /*oti menei spaces */
  377.     fn[8] = 0;              /*end of string */
  378.  
  379.     /*Convert se dir_entry->ext format */
  380.     str_upper_case(ext);            /*Upper case */
  381.     for (tmp = ext; *tmp; tmp++);       /*sto end of string */
  382.     for (; tmp < ext+4; tmp++)*tmp = ' ';   /*oti menei spaces */
  383.     ext[3] = 0;             /*end of string */
  384.     /*Ksekiname to browse tou katalogou */
  385.     fat12_read_cluster(fat,cluster,(uint32)dir);
  386.     tmp = dir;
  387.     while (1){
  388.         if (tmp >= (uint8*)(dir + 512)){    /*Pera ap ta oria */
  389.             if (cluster != 2){  /*oxi gia to root dir */
  390.                 cluster = fat12_get_next_cluster(fat, cluster); /*pame sto next cluster */
  391.                 if (cluster && cluster <= 0xFF8){   /*An yparxei .. */
  392.                     fat12_read_cluster(fat,cluster,(uint32)dir);
  393.                     tmp = dir;
  394.                 }
  395.                 else                    /*Allios return */
  396.                     return 0;
  397.             }
  398.         }
  399.         if (*tmp == 0) break;               /*End of directory */
  400.         if (*tmp == 0xE5) {             /*Den xrisimopoieitai to entry */
  401.             tmp += sizeof(dir_entry_t);
  402.             continue;
  403.         }
  404.         if (*tmp == '.') {              /*dor or dotdot entry */
  405.             tmp += sizeof(dir_entry_t);
  406.             continue;
  407.         }
  408.         if ((*tmp & 0xF0) == 0x40){     /*Long Directory enties */
  409.             while ((*tmp & 0x0F) != 0x01){  /*Last Long dir Entry */
  410.                 tmp += sizeof(dir_long_t);  /*next */
  411.                 /*Epidi exoume loop, psaxnoume ki edw min vgoume ap ta oria tou sect */
  412.                 if (tmp >= (uint8*)(dir + 512)){
  413.                     if (cluster != 2){
  414.                         cluster = fat12_get_next_cluster(fat, cluster);
  415.                         if (cluster && cluster <= 0xFF8){
  416.                             fat12_read_cluster(fat,cluster,(uint32)dir);
  417.                             tmp = dir;
  418.                         }
  419.                         else
  420.                             return 0;
  421.                     }
  422.                 }
  423.             }
  424.             tmp += sizeof(dir_long_t);  /*Telos prospername kai to last */
  425.         }
  426.         /*Kai kapou edw vriskomaste se pragmatiko Directory Entry */
  427.         dent = (dir_entry_t*)tmp;
  428.         memcpy(buff, dent->filename, 8);
  429.         buff[9] = 0;
  430.         memcpy(ebuff, dent->ext, 3);
  431.         ebuff[3] = 0;
  432.         if (strcmp(fn, buff) == 0 && strcmp(ext, ebuff) == 0){
  433.             ret = kmalloc(sizeof(dir_entry_t));
  434.             memcpy((char*)ret, (char*)dent, sizeof(dir_entry_t));
  435.             return ret; /*Vrikame to entry, ret */
  436.         }
  437.         tmp += sizeof(dir_entry_t);
  438.     }
  439.     return 0;   /*Den vrikame tpt */
  440. }
  441.  
  442. static void fat12_read_cluster(fat_t* fat,uint16 cluster, uint32 buffer){
  443. /*Diavazei ena cluster kai to sozei ston buffer */
  444.     uint32 sect,i;
  445.     char *p = (char*)buffer;
  446.     sect = fat12_get_cluster_sector(fat,cluster);
  447.     for (i = 0; i < fat->bs->sectors_per_cluster; i++)  /*An to cluster exei panw apo 1 sector */
  448.         fat->dev->read_dev(sect+i,fat->dev->attr,(uint32)(&p[512*i]));
  449. }
  450.  
  451. static uint32 fat12_get_cluster_sector(fat_t* fat,uint16 cluster){
  452. /*Mas dinei to Sector opou vriskete ena cluster, gia na to diavasoume */
  453.     if (cluster >=3)
  454.         return (fat->first_data_cluster_sect + ((cluster-3)*fat->bs->sectors_per_cluster));
  455.     return fat->first_data_sector;  /*Cluster 2 */
  456. }
  457.  
  458. static uint16 fat12_get_next_cluster(fat_t* fat,uint16 cluster){
  459. /*Psaxnei sto FAT kai mas epistrefei to Next Cluster tou chain */
  460.     uint32 fat_offset = cluster + (cluster / 2) ;   /* Polaplasiasmos *1,5 (efoson einai 12 bit per addr */
  461.     void* tmp = &fat->FAT[fat_offset];      /* Pigenoume sto offset panw sto FAT */
  462.     uint16 table_value;             /* Tha parei to value */
  463.     uint32 val = (*(uint32*)tmp) & 0x0000FFFF;  /*pernoume 3 bytes */
  464.     uint32 t = (*(uint32*)tmp);
  465.  
  466.     if(cluster & 0x0001){   /*Mono cluster */
  467.         table_value = (uint16)(val >> 4);   /*Pernei to word Shifted 4 bits */
  468.     }
  469.     else            /*Zigo cluster */
  470.         table_value = (uint16)(val & 0x0FFF);   /*Pernei to address opos einai */
  471.  
  472.     return table_value;
  473. }
Add Comment
Please, Sign In to add comment