⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesys.c

📁 Linux下简单文件系统的操作 具体可以实现目录得建立删除等等功能
💻 C
字号:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include "filesys.h"#define DEBUG#define RevByte(low,hight) ((hight)<<8|(low))#define RevWord(lowest,lower,higher,highest) ((highest)<<24|(higher)<<16 |(lower)<<8|lowest)struct BootDescriptor_t bdptor;struct Entry *curdir=NULL; int fd;unsigned char fatbuf[0x1200]; void ScanBootSector(){unsigned char buf[SECTOR_SIZE];int ret,i;if((ret=read(fd,buf,SECTOR_SIZE))<0)perror("read boot sector failed");for(i=0;i<=10;i++) bdptor.Oem_name[i]=buf[i+0x03];bdptor.Oem_name[i]='\0';bdptor.BytesPerSector    =RevByte(buf[0x0b],buf[0x0c]);bdptor.SectorsPerCluster =buf[0x0d];bdptor.ReservedSectors    =RevByte(buf[0x0e],buf[0x0f]);bdptor.FATs              =buf[0x10];bdptor.RootDirEntries    =RevByte(buf[0x11],buf[0x12]);bdptor.LogicSectors      =RevByte(buf[0x13],buf[0x14]);bdptor.MediaType         =buf[0x15];bdptor.SectorsPerFAT     =RevByte(buf[0x16],buf[0x17]);bdptor.SectorsPerTrack   =RevByte(buf[0x18],buf[0x19]);bdptor.Heads             =RevByte(buf[0x1a],buf[0x1b]);bdptor.HiddenSectors     =RevByte(buf[0x1c],buf[0x1d]);#ifdef  DEBUG printf("Oem_name \t\t%s\n""BytesPerSector \t\t%d\n""SectorsPerCluster \t%d\n""ReservedSectors \t%d\n""FATs \t\t\t%d\n""RootDirEntries \t\t%d\n""LogicSectors \t\t%d\n""MediaType \t\t%x\n""SectorsPerFAT \t\t%d\n""SectorsPerTrack \t%d\n""Heads \t\t\t%d\n""HiddenSectors \t\t%d\n",bdptor.Oem_name,bdptor.BytesPerSector,bdptor.SectorsPerCluster,bdptor.ReservedSectors,bdptor.FATs,bdptor.RootDirEntries,bdptor.LogicSectors,bdptor.MediaType,bdptor.SectorsPerFAT,bdptor.SectorsPerTrack,bdptor.Heads,bdptor.HiddenSectors);#endif}void findDate(unsigned short *year,unsigned short *month,unsigned short *day,unsigned char info[2]){int data;data =RevByte(info[0],info[1]);*year=((data & MASK_YEAR)>>9)+1980;*month=(data & MASK_MONTH)>>5;*day=(data &MASK_DAY);}void findTime(unsigned short *hour,unsigned short *min,unsigned short *sec,unsigned char info[2]){int time; time=RevByte(info[0],info[1]);  *hour=(time & MASK_HOUR)>>11;*min=(time & MASK_MIN)>>5;*sec=(time & MASK_SEC)*2;}/* bug for fix *//*void FileNameFormat_old(unsigned char *name){unsigned char *q,*k,filename[12];q=name;k=name;while (*q != '')  q++;*q = '\0';strcpy(filename,k);// name*q = '';strcat (filename,".");while ( *q == '') q++;k=q;strcat(filename,k);// extensionstrcpy(name,filename);}*/void FileNameFormat(unsigned char *name){unsigned char *p;p=name+strlen(name)-1;/* stripp the traling space */while(*p == ' ') p--;p++;*p='\0';}void ScanRootEntry(){struct Entry entry;int ret,offset;if((ret=lseek(fd,ROOTDIR_OFFSET,SEEK_SET)) <0)perror("lseek ROOTDIR_OFFSET failed");offset=ROOTDIR_OFFSET;printf("\nA:\\ls");printf("\n\tname\tdate\t\t time\t\tsector\tsize\t\tattr\n");while(offset < DATA_OFFSET){ret=GetEntry(&entry); offset+=abs(ret);if(ret>0){ printf("\t%12s""\t%d:%d:%d""\t%d:%d:%d""\t\t%d""\t%d""\t\t%s\n",entry.short_name,entry.year,entry.month,entry.day,entry.hour,entry.min,entry.sec,entry.size,entry.FirstCluster, (entry.subdir)? "dir":"file");}}printf("\n");}/**Argument:entry,Type:struct Entry**Return:offset for success,-count for fail or no entry*Function:get entry fron form cluster or root dir*Comment:One Entry maybe 32,64,96 Bytes*/int GetEntry(struct Entry *pentry){int ret,i;int count=0;unsigned char buf[DIR_ENTRY_SIZE],info[2];if((ret=read(fd,buf,DIR_ENTRY_SIZE))<0)  perror("read entry failed");count+=ret;if(buf[0]==0xe5 || buf[0]==0x00) return -1*count; else{while(buf[11]==0x0f) { if((ret=read(fd,buf,DIR_ENTRY_SIZE))<0) perror("read root dir failed");count+=ret;}for(i=0;i<=10;i++) pentry->short_name[i]=buf[i];pentry->short_name[i]='\0';}FileNameFormat(pentry->short_name);info[0]=buf[22];info[1]=buf[23];findTime(&(pentry->hour),&(pentry->min),&(pentry->sec),info);info[0]=buf[24]; info[1]=buf[25];findDate(&(pentry->year),&(pentry->month),&(pentry->day),info);pentry->FirstCluster = RevByte (buf[26],buf[27]);pentry->size = RevWord (buf[28],buf[29],buf[30],buf[31]);pentry->readonly = (buf[11] &ATTR_READONLY) ? 1:0;pentry->hidden   = (buf[11] &ATTR_HIDDEN)   ? 1:0;pentry->system   = (buf[11] &ATTR_SYSTEM)   ? 1:0;pentry->vlabel   = (buf[11] &ATTR_VLABEL)   ? 1:0;pentry->subdir   = (buf[11] &ATTR_SUBDIR)   ? 1:0;pentry->archive  = (buf[11] &ATTR_ARCHIVE)  ? 1:0;return count;}int fd_ls(){int ret,offset,cluster_addr;struct Entry entry;printf("\nA:\\ls\n");/* printf("\tname\tdate\t\t time\t\tsector\tsize\t\tattr\n"); */if (curdir == NULL) {ScanRootEntry(fd); }else{ cluster_addr = DATA_OFFSET+(curdir->FirstCluster - 2) * SECTOR_SIZE;if ((ret = lseek(fd,cluster_addr,SEEK_SET)) < 0)perror("lseek cluster_addr failed");offset = cluster_addr;while (offset < cluster_addr +SECTOR_SIZE){ret = GetEntry(&entry);offset += abs(ret);if (ret > 0){printf( "%12s\t""%d:%d:%d\t""%d:%d:%d\t\t""%d\t""%d\t\t""%s\n",entry.short_name,entry.year,entry.month,entry.day,entry.hour,entry.min,entry.sec,entry.size,entry.FirstCluster,(entry.subdir)?"dir":"file");}}}return 0;}int ScanEntry(char *entryname,struct Entry *pentry,int mode){int ret,offset,i;int cluster_addr;char uppername[80];for (i = 0;i<strlen(entryname);i++)uppername[i] = toupper(entryname[i]);uppername[i] = '\0';if (curdir == NULL){if ((ret == lseek(fd,ROOTDIR_OFFSET,SEEK_SET)) < 0)perror ("lseek ROOTDIR_OFFSET failed");offset = ROOTDIR_OFFSET;while (offset < DATA_OFFSET){ret = GetEntry(pentry);offset += abs(ret);if (pentry->subdir == mode && !strcmp(pentry->short_name,uppername))return offset;}return -1;}else{cluster_addr = DATA_OFFSET + (curdir->FirstCluster - 2) * SECTOR_SIZE;if ((ret == lseek(fd,cluster_addr,SEEK_SET)) < 0)perror ("lseek cluster_addr failed");offset = cluster_addr;while(offset < cluster_addr + SECTOR_SIZE){ret = GetEntry(pentry);offset += abs (ret);if (pentry->subdir == mode && !strcmp(pentry->short_name,uppername))return offset;}return -1;}}/*Argument:dir Type char**Return:1 if success,or -1 if filed*Function:change dir to parent dir or subdireg"cd.."or"cd subdir",full path not support*/int fd_cd(char *dir){struct Entry *pentry;int ret;printf("\nA:\\cd %s\n",dir);if (!strcmp(dir,"."))return 1;if (!strcmp(dir,"..") && curdir == NULL)return 1;/* ??? */pentry = (struct Entry*)malloc(sizeof(struct Entry));ret = ScanEntry(dir,pentry,1);if (ret < 0){printf ("no such dir\n");free(pentry);return -1;}free (curdir);curdir = pentry;#ifdef DEBUG/*printf("%12s\t"*//*"%d:%d:%d\t"*//*"%d:%d:%d\t"*//*"%d\t"*//*"%d\t\t"*//*"%s\n",*//*prntry->short_name,*//*pentry->year,pentry->month,pentry->day,*//*pentry->hour,pentry->min,pentry->sec,*//*pentry->size,*//*pentry->FirstCluster*//*(pentry->subdir)?"dir":"file"*/#endifreturn 1;}unsigned short GetFatCluster(unsigned short prev){unsigned short next,fatentry;int index;index = prev *1.5;fatentry = RevByte (fatbuf[index],fatbuf[index+1]);if (prev % 2 ==1) next = fatentry >> 4;else next = fatentry & 0x0fff;return next;}void ClearFatCluster(unsigned short cluster){int index;index = (int)cluster * 1.5;if (cluster % 2 == 1){fatbuf[index] &= 0x0f;fatbuf[index+1] &= 0x00;}else{fatbuf[index] &= 0x00;fatbuf[index+1] &= 0xf0;}}int fd_rm(char *filename){struct Entry *pentry;int ret;unsigned char c;unsigned short seed,next;printf("\nA:\\rm %s\n",filename);pentry = (struct Entry*)malloc(sizeof(struct Entry));ret = ScanEntry(filename,pentry,0);if(ret < 0){printf("no such file\n");free(pentry);return -1;}seed = pentry->FirstCluster;while ((next = GetFatCluster(seed)) != 0x0fff){seed = next;ClearFatCluster(next);}ClearFatCluster(pentry->FirstCluster);c = 0xe5;if (lseek(fd,ret-0x40,SEEK_SET) < 0)perror("lseek fd_rm failed");if (write(fd,&c,1) < 0)perror("write failed");if(lseek(fd,ret-0x20,SEEK_SET) < 0)perror("lseek fd_rm failed");if(write(fd,&c,1) <  0)perror("write failed");free(pentry);if (WriteFat()<0)exit(1);printf("file rm OK!\n");return 1;}int WriteFat(){if(lseek(fd,FAT_ONE_OFFSET,SEEK_SET) < 0){perror("lseek failed");return -1;}if(write(fd,fatbuf,0x1200) < 0){perror("read failed");return -1;}if(lseek(fd,FAT_TWO_OFFSET,SEEK_SET) < 0){perror("lseek failed");return -1;}if(write(fd,fatbuf,0x1200) < 0){perror("read failed");return -1;}return 1;}int ReadFat(){ if(lseek(fd,FAT_ONE_OFFSET,SEEK_SET)<0){ perror("lseek failed");return -1;}if(read(fd,fatbuf,0x1200)<0){  perror("read failed");return -1;}}int main(){if((fd=open(DEVNAME,O_RDWR))<0) perror("open failed"); if (ReadFat()<0)  exit(1); ScanBootSector();ScanRootEntry();/*test one*/fd_cd("testdir");/*test two */fd_ls();/*test three*/ fd_rm("testfile"); close(fd);free(curdir);return 0;} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -