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

📄 libfat.c

📁 Support library to access and manipulate FAT12 / FAT16 / FAT32 file systems - Includes a FUSE filesy
💻 C
📖 第 1 页 / 共 5 页
字号:
	WORD val;	DWORD out;					//  lo hi	if (N%2 == 0) {	//  XX -X		val = 0;				((BYTE *) &val)[0] = (BYTE) V->fat[((int) (N * 1.5))];		((BYTE *) &val)[1] = (BYTE) V->fat[((int) (N * 1.5)) + 1];		((BYTE *) &val)[1] &= 0x0F;			} else { 			 /* odd     X- XX			 	    	 \  \			            XX -X   */		val =0;		((BYTE *) &val)[0] = (BYTE) V->fat[((int) (N * 1.5))];		((BYTE *) &val)[1] = (BYTE) V->fat[((int) (N * 1.5)) + 1];						((BYTE *) &val)[0] = (((BYTE *) &val)[0] >> 4);		((BYTE *) &val)[0] |= (((BYTE *) &val)[1] << 4);		((BYTE *) &val)[1] = (((BYTE *) &val)[1] >> 4);	}		out = val;	*Value = EFD(out);	return 0;		}static int fat12_write_entry(Volume_t *V, DWORD N, int FatNum, DWORD Value) {	WORD val;	val = Value;	val = EFW(val);	// now val is little endian word			if (N%2 == 0) { // XX -X : just mix hi byte		*((BYTE *) (V->fat + ((int) (N * 1.5)))) = ((BYTE *) &val)[0];		*((BYTE *) (V->fat + ((int) (N * 1.5)) + 1)) &= 0xF0;		*((BYTE *) (V->fat + ((int) (N * 1.5)) + 1)) |= ( ((BYTE *) &val)[1] & 0x0F );	} else {	//		XX -X	//       /  /	//		X- XX		*((BYTE *) (V->fat + ((int) (N * 1.5)))) &= 0x0F;		*((BYTE *) (V->fat + ((int) (N * 1.5)))) |= ( (((BYTE *) &val)[0] << 4) );		*((BYTE *) (V->fat + ((int) (N * 1.5)) + 1)) = ( (((BYTE *) &val)[1] << 4) );				*((BYTE *) (V->fat + ((int) (N * 1.5)) + 1)) |= ( (((BYTE *) &val)[0] >> 4) );	}//	fprintf(stderr,"fat12_write_entry: N:%u, value:%u\n",N,Value);	return 0;}static int fat12_unlinkn(Volume_t *V, DWORD Cluster) {  int   Res;  DWORD Next;  int 	i = 0;	  if ((fat_isfree(V,Cluster)) || (fat_iseoc(V,Cluster))) return 0;	  if (fat_isbad(V,Cluster)) return -1;    do {    /* Read the next entry in the chain */    if ( (Res = fat12_read_entry(V, Cluster, 0, &Next)) != 0 ) { 		fprintf(stderr,"unlinkn() error cycle: %d Line: %d",i, __LINE__);		return -1; 	}    /* Update every FAT in the volume */    if ( (Res = fat12_write_entry(V, Cluster, 0, 0)) != 0 ) { 		fprintf(stderr,"unlinkn() error cycle: %d Line: %d",i,__LINE__);	  	return -1; 	}    /* Update FSInfo Sector values	*/    V->freecnt++;//    if (Cluster < V->nextfree ) ->nextfree = Cluster;    Cluster = Next; 	i++; }  while (!(fat_iseoc(V,Next)));  return 0;}/* GENERAL WRAPPERS FOR THE ABOVE FUNCTIONS                    */static int fat_read_entry(Volume_t *V, DWORD N, int FatNum, DWORD *Value) {    if (V->FatType == FAT32) {        return fat32_read_entry(V, N, FatNum, Value);    } else if (V->FatType == FAT16) {      return fat16_read_entry(V, N, FatNum, Value);    } else {      return fat12_read_entry(V, N, FatNum, Value);    }    return 0;}#if 0/* Useless atm	*/static int fat_write_entry(Volume_t *V, DWORD N, int FatNum, DWORD Value) {    if (V->FatType == FAT32) {        return fat32_write_entry(V, N, FatNum, Value);    } else if (V->FatType == FAT16) {      return fat16_write_entry(V, N, FatNum, Value);    } else {      return fat12_write_entry(V, N, FatNum, Value);    }    return 0;}#endifstatic int fat_writen_entry(Volume_t *V, DWORD N, DWORD Value) {    if (V->FatType == FAT32) {        return fat32_writen_entry(V, N, Value);    } else if (V->FatType == FAT16) {      return fat16_write_entry(V, N, 0 ,Value);    } else {      return fat12_write_entry(V, N, 0, Value);    }    return 0;}static int fat_unlinkn(Volume_t *V, DWORD Cluster) {    if (V->FatType == FAT32) {        return fat32_unlinkn(V, Cluster);    } else if (V->FatType == FAT16) {      return fat16_unlinkn(V, Cluster);    } else {      return fat12_unlinkn(V, Cluster);    }    return 0;}/* set the volume as dirty, 										*//* the routine set the 5th high bit to 0 for dirty flag				*//* bitmaks: 0x08000000. 											*/static int fat_mark_dirty(Volume_t *V) {		DWORD val;		int Res;	if (V->FatType == FAT32)  {		DWORD dirty32 = 0xF7FFFFFF;		if ((Res = fat_read_entry(V, 1, 0, &val)) != 0) {			perror("fat_read_entry error");			return Res;		}				val = val & dirty32;				if ((Res = fat_writen_entry(V, 1, val)) != 0) {			perror("fat_write_entry error");			return -1;		}		} else if (V->FatType == FAT16)  {		WORD  dirty16 = 0x8000;		WORD val16;        if ((Res = fat_read_entry(V, 1, 0, &val)) != 0) {            perror("fat_read_entry error");            return Res;        }				val16 =  val;        val16 = val16 & dirty16;        if ((Res = fat_writen_entry(V, 1, (DWORD) val16)) != 0) {            perror("fat_write_entry error");            return -1;        }	}	return 0;			}/* set the volume as clean, 										*//* the routine set the 5th high bit to 1 for clean flag				*//* bitmaks: 0x08000000. 											*/static int fat_mark_clean(Volume_t *V) {        DWORD val;        int Res;	if (V->FatType == FAT32) {		DWORD clean32 = 0x08000000;		 		if ((Res = fat_read_entry(V, 1, 0, &val)) != 0) {			perror("fat32_read_entry error");			return Res;		}					val = val | clean32;				if ((Res = fat_writen_entry(V, 1, val)) != 0) {			perror("fat32_write_entry error");			return -1;		}			} else if  (V->FatType == FAT16)  {		WORD  clean16 = 0x8000;		WORD  val16;        if ((Res = fat_read_entry(V, 1, 0, &val)) != 0) {            perror("fat_read_entry error");            return Res;        }        val16 =  val;        val16 = val16 | clean16;        if ((Res = fat_writen_entry(V, 1, (DWORD) val16)) != 0) {            perror("fat_write_entry error");            return -1;        }	}	return 0;		}#endif /* #ifdef FATWRITE *//*************************************************************************	Functions to work on Directory entries			 	*************************************************************************/static void printVolumeData(Volume_t *V) {	DWORD sz;	if (V->FatType == FAT32) {		sz = EFD(V->Bpb.BPB_FATSz32);	} else {		sz = EFW(V->Bpb.BPB_FATSz16);		fprintf(stderr,"root dir off : %lld \n", byte_offset(V,1,0));			}		fprintf(stderr,"dataclusters :%u  \n", V->DataClusters);	fprintf(stderr,"first data byte : %lld \n", V->fdb64   );	fprintf(stderr,"1st fat off :  %d \n", V->rsvdbytecnt );	fprintf(stderr,"2nd fat off :  %d\n", V->rsvdbytecnt+ (sz * V->bps) );	fprintf(stderr,"fat_eoc_value: %u\n", fat_eocvalue(V));	fprintf(stderr,"fat_eoc_value is eoc?: %d\n", fat_iseoc(V,fat_eocvalue(V)));	return ;}static int libfat_determine_fattype(Volume_t *V) {    int res;    off_t fsi_offset;    char type[9];    sprintf(type,"FAT12   ");    if ((res = memcmp( (char *) &(((char *) &(V->Bpb))[54]), type, 8)) == 0) { V->FatType = FAT12; fprintf(stderr,"fat type: FAT12\n"); return 0; }    sprintf(type,"FAT16   ");    if ((res = memcmp( (char *) &(((char *) &(V->Bpb))[54]), type, 8)) == 0) { V->FatType = FAT16; fprintf(stderr,"fat type: FAT16\n");return 0; }    sprintf(type,"FAT32   ");    if ((res = memcmp( (char *) V->Bpb.BS_FilSysType, type, 8)) == 0) {				fprintf(stderr,"fat type: FAT32. Fsi at %u\n",EFW(V->Bpb.BPB_FSInfo));        V->FatType = FAT32;        fsi_offset = EFW(V->Bpb.BPB_FSInfo) * EFW(V->Bpb.BPB_BytsPerSec);        // Only for FAT32		fprintf(stderr,"Fsioff: %d, size: %d\n",(int) fsi_offset, sizeof(FSInfo_t));        if ( (res = lseek(V->blkDevFd, fsi_offset, SEEK_SET)) != fsi_offset ) { perror("FSI lseek() error"); return -1; }        if ( (res = readn(V->blkDevFd, &(V->Fsi), sizeof(FSInfo_t))) != sizeof(FSInfo_t) ) { perror("FSI readn() error"); return -1; }		fprintf(stderr,"--- nxtfree --- :%u\n",EFD(V->Fsi.FSI_Nxt_Free)); 		fprintf(stderr,"--- freecnt --- :%u\n",EFD(V->Fsi.FSI_Free_Count)); 				fflush(stderr);        return 0;    }    /* else */    return -1;/* Now we can determine  FAT type *//*    if (CountofClusters < 4085) {        sprintf(buf,"FAT12");    } else if (CountofClusters < 65525) {        sprintf(buf,"FAT16");    } else {        sprintf(buf,"FAT32");    }*/}/* load the whole fat into memory for fat12/16 volumes  */static int libfat_initialize_fat(Volume_t *V) {	int res;    int fatsz = 0;  // total size of the fat in bytes	/* Lets determine the total size of the fat in bytes */    if (V->FatType == FAT16) {        fatsz = (V->DataClusters + 2) * sizeof(WORD);    } else if (V->FatType == FAT12) {    	fatsz = ((V->DataClusters + 2) / 2) * 3;        if (((V->DataClusters + 2) % 2) != 0) fatsz += 2;	} else {		fprintf(stderr,"unknown fat type in initialise_fat\n");		return -1;	}		/* Memory Map or Load/Restore the FAT? Load/restore for the moment	*/	V->fat = malloc(fatsz); // up to 128k of memory for the biggest fat16 ever.	memset(V->fat, 0, fatsz);	if ( (res = lseek64(V->blkDevFd, V->rsvdbytecnt, SEEK_SET)) < 0) {		fprintf(stderr,"lseek() error in initialize fat(), off:%d\n",V->rsvdbytecnt);		return res;	}	/*  read()      */					if ( (res = readn(V->blkDevFd, V->fat, fatsz)) != fatsz) {		fprintf(stderr,"readn() error in initialize fat. size: %d\n", fatsz);		return -1;	}/*	fprintf(stderr,"\n\n\n\n\n");	for(i=0; i< 200; i++) {		fprintf(stderr,"%d: %X ",i,(BYTE) V->fat[i]);	//		if ((i %2) == 0) fprintf(stderr, " ");	}	fprintf(stderr,"\n\n\n\n\n");	getc(stdin);*/		/* we have now the whole fat in V->fat. We need to write it down in finalize in all the fat copies in the volume	*/	return 0;}static int libfat_scan_for_free(Volume_t *V) {    int i,res;  // int is ok, because this routine is only for fat12/16    int count=0;    DWORD val;    for (i=2; i<=(V->DataClusters + 1); i++) {        if ((res=fat_read_entry(V,i,0,&val)) != 0) { fprintf(stderr,"scan_for_free error\n"); return -1; }        if ( fat_isfree(V,val) ) count++;    }    return count;}static int libfat_initialize_freelist(Volume_t *V) {    int res;    V->fstfclus=0;    V->fclusz=0;    if (V->FatType == FAT32) {        V->freecnt = EFD(V->Fsi.FSI_Free_Count);        V->nextfree = EFD(V->Fsi.FSI_Nxt_Free);        if ( !(FAT32_LEGALCLUS(V->nextfree)) || (V->nextfree > (V->DataClusters + 1) ) ) {  //to fix 1st condition            fprintf(stderr,"invalid next free field: %u\n",V->nextfree); return -1; }        if ((res = fat_populate_freelist(V)) <= 0) { perror("populate freelist error"); return -1; }    } else {    // FAT12 || FAT16		if ((res = libfat_initialize_fat(V)) < 0 ) { fprintf(stderr,"initialize fat error\n"); return -1; }        /* we need to scan the fat to find the free cluster count */        V->freecnt = libfat_scan_for_free(V);        if (V->freecnt < 0) { fprintf(stderr,"initialize freelist error\n"); return -1; }        V->nextfree = 2;    }    return 0;}/*	Initialise	a Volume_t structure with the data  found in the BootSector	*//*	NB: the pathname must refer to a valid *FAT32* filesystem and must be 	*//*  canonical name															*//*	FAT12/16 NOT SUPPORTED right now										*/int	fat_partition_init(Volume_t *V, char *pathname, int flags) {	// todo: add uid and gid;    DWORD RootDirSectors = 0;	// Only for FAT12/16    DWORD FATSz;    DWORD FirstDataSector;    DWORD TotSec;    DWORD CountofClusters;    DWORD DataSec;	int fd,res;/*  Variables we need to read from Boot Sector      unsigned short int  BPB_RootEntCnt;    unsigned short int  BPB_BytsPerSec;    unsigned short int  BPB_FATSz16;    unsigned int        BPB_FATSz32;    unsigned short int  BPB_TotSec16;    unsigned int        BPB_TotSec32;    unsigned short int  BPB_ResvdSecCnt;    unsigned char       BPB_NumFATs;    unsigned short int  BPB_SecPerClus;  ------------------------------------------  */    V->uid = 0; //=uid;    V->gid = 0; //=gid;    V->fat = NULL;	if (sizeof(off64_t) < 8) {		perror("off64_t not supported properly by this system. the driver wont work properly");		return -1;	}	if (sizeof(DWORD) != 4) {		perror("DWORD not supported properly by this system. the driver wont work properly");		return -1;	}	if (sizeof(long long int) < 8) {		perror("long long int not supported properly by this system. the driver wont work properly");		return -1;	}#ifdef FATWRITE	if (flags & FAT_WRITE_ACCESS_FLAG) {		if ( (fd = open(pathname, O_RDWR)) == -1 ) 		perror("open() (RDWR) error");	} else {		if ( (fd = open(pathname, O_RDONLY)) == -1 ) 			perror("open() (RDONLY) error");	}#else	if ( (fd = open(pathname, O_RDONLY)) == -1 ) 		perror("open() (RDONLY) error");#endif		V->blkDevFd = fd;	if ( (res = readn(fd, &(V->Bpb), sizeof(Bpb_t))) != sizeof(Bpb_t))		//we read directly from da disk (NB FAT32 BPB)		perror("BPB readn() error");/* 	--------------------------------------------------------------------		*/    if ( V->Bpb.BPB_FATSz16 != 0) { /* 0 is endianess independent */        FATSz = EFW(V->Bpb.BPB_FATSz16);    } else {        FATSz = EFD(V->Bpb.BPB_FATSz32);    }	    if ( V->Bpb.BPB_TotSec16 != 0) {        TotSec = EFW(V->Bpb.BPB_TotSec16);    } else {        TotSec = EFD(V->Bpb.BPB_TotSec32);    }	RootDirSectors = (EFW(V->Bpb.BPB_RootEntCnt) * 32) / EFW(V->Bpb.BPB_BytsPerSec) ;

⌨️ 快捷键说明

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