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

📄 filesim.c

📁 包装了一个开源的FAT16文件系统
💻 C
字号:
//file: filesim.c
//使用一个文件作为一个虚拟的FAT16卷容器,来测试fat16文件系统。同时导出一个块设备接口
#include "fsdefs.h"
#include "filesim.h"
#include "blkmdd.h"
#include <stdio.h>
#include <memory.h>
//-----------------------导出块设备接口----------------------
UFAV FileSimRdSct( U32 secNum, U8 *pBuf);
UFAV FileSimWrSct( U32 secNum, const U8* IN pBuf);


#pragma pack(1)

typedef struct _DS_RWStat
{
	U32 rdCnt;
	U32 wrCnt;
	U32 rdByteCnt;
	U32 wrByteCnt;
}DS_RWStat;

//为伪造优盘而设计的一个简化的FAT描述表
typedef struct _DS_SimFat
{
	U16 bytesPerSector;
	U8	sectorsPerCluster;
	U16 reservedSectorCnt;
	U8	fatCnt;
	U16 maxRootEntries;
	U16 sectorCnt16;
	U8	mediaDesc;
	U16 sectorsPerFat;
	U16 sectorsPerTrack;
	U16 headCnt;
	U32 hiddenSectorCnt;
	U32 sectorCnt;
}DS_SimFat;
#pragma pack()


static BOOL sg_isStarted=FALSE;
static DS_RWStat sg_rwStat;
FILE *fp;

//为了伪造优盘随便定的一些值
#define CON_SectorOffset		8
#define CON_ReservedSectorCnt	16
#define CON_MaxRootEntries		40
#define CON_SectorsPerFat		212
#define CON_FatCnt				2


BOOL FileSim_Startup()
{
	U8 buffer[512];
	U32 byteRem;
	I32 i;
	U32 *pU32;
	DS_SimFat *pfat;
	if (sg_isStarted)
	{
		return TRUE;
	}
	fp=fopen("simdisk.dat","rb");
	if (!fp)
	{
		fp=fopen("simdisk.dat","wb+");
		if (fp)
		{
			sg_isStarted=TRUE;
		}

		//产生一个16MB的文件
		byteRem= 16*1024*1024;
		fseek(fp,0,SEEK_SET);
		memset(buffer,0,512);
		while(byteRem)
		{
			fwrite(buffer,1,512,fp);
			byteRem-=512;
		}


		//制造分区描述信息为FAT16
		buffer[0x01be+4]= 0x06; //PARTITION_TYPE_FAT16;
		//制造分区所有偏移量信息
		pU32= (U32 *) (buffer+0x1be+8);
		*pU32++= CON_SectorOffset;
		//制造分区容量信息
		*pU32= 16*1024*1024- 512*CON_SectorOffset;
		fseek(fp,0,SEEK_SET);
		fwrite(buffer,1,512,fp);


		//制造fat描述表
		pfat= (DS_SimFat *) (buffer+0x0b);
		pfat->bytesPerSector=512;
		pfat->sectorsPerCluster=1;
		pfat->reservedSectorCnt=CON_ReservedSectorCnt;
		pfat->fatCnt=CON_FatCnt;
		pfat->maxRootEntries= CON_MaxRootEntries;
		pfat->sectorCnt16=0;
		pfat->mediaDesc=0xf8;
		pfat->sectorsPerFat=CON_SectorsPerFat;
		pfat->sectorsPerTrack=4096;
		pfat->headCnt=2;
		pfat->hiddenSectorCnt=0;
		pfat->sectorCnt= 16*1024*1024/512 - CON_SectorOffset;

		fseek(fp,512*CON_SectorOffset,SEEK_SET);
		fwrite(buffer,1,512,fp);

		//制造初始化过的空白分配表
		memset(buffer,0,512);
		fseek(fp,512*( CON_SectorOffset+ CON_ReservedSectorCnt), SEEK_SET);
		buffer[0]=0xff;
		buffer[1]=0xf0;
		buffer[2]=0xff;
		buffer[3]=0xf0;
		fwrite(buffer,1,512,fp);
		memset(buffer,0,4);
		for (i=1;i<CON_SectorsPerFat*CON_FatCnt;i++)
		{
			fwrite(buffer,1,512,fp);
		}
		memset(&sg_rwStat,0,sizeof(sg_rwStat));
	}
	else
	{
		fclose(fp);
		fp=fopen("simdisk.dat","rb+");
		sg_isStarted=TRUE;
	}
	return sg_isStarted;

}

BOOL FileSim_Cleanup()
{
	if (!sg_isStarted)
	{
		return FALSE;
	}
	sg_isStarted=FALSE;
	fclose(fp);
	fp=NULL;
	return TRUE;
}


uint8_t FileSim_read(uint32_t offset, uint8_t* buffer, uint16_t length)
{
	fseek(fp,offset,SEEK_SET);
	fread(buffer,1,length,fp);
	sg_rwStat.rdCnt++;
	sg_rwStat.rdByteCnt+=length;
	return 1;
}

uint8_t FileSim_write(uint32_t offset, const uint8_t* buffer, uint16_t length)
{
	fseek(fp,offset,SEEK_SET);
	fwrite(buffer,1,length,fp);
	sg_rwStat.wrCnt++;
	sg_rwStat.wrByteCnt+=length;
	return 1;
}

uint8_t FileSim_read_interval(uint32_t offset, uint8_t* buffer, uint16_t interval, uint16_t length, FileSim_read_interval_handler_t callback, void* p)
{

	if(!buffer || interval == 0 || length < interval || !callback)
		return 0;

	while(length >= interval)
	{
		/* as reading is now buffered, we directly
		* hand over the request to sd_raw_read()
		*/
		if(!FileSim_read(offset, buffer, interval))
			return 0;
		if(!callback(buffer, offset, p))
			break;
		offset += interval;
		length -= interval;
	}
	return 1;
}

uint8_t FileSim_write_interval(uint32_t offset, uint8_t* buffer, uint16_t length, FileSim_write_interval_handler_t callback, void* p)
{
	
	uint8_t endless = (length == 0);
	uint16_t bytes_to_write;
	if(!buffer || !callback)
		return 0;
	
	while(endless || length > 0)
	{
		bytes_to_write = callback(buffer, offset, p);
		if(!bytes_to_write)
			break;
		if(!endless && bytes_to_write > length)
			return 0;

		/* as writing is always buffered, we directly
		* hand over the request to sd_raw_write()
		*/
		if(!FileSim_write(offset, buffer, bytes_to_write))
			return 0;

		offset += bytes_to_write;
		length -= bytes_to_write;
	}

	return 1;
}

//以下是为blkmdd导出的块设备接口

BOOL PHDInits(void)
{
	PHDRegisterHandlers(FileSimRdSct, FileSimWrSct);
	return FileSim_Startup();
}

BOOL PHDCleanup()
{
	return FileSim_Cleanup();
}

UFAV FileSimRdSct(U32 secNum, U8 *pBuf)
{
	return FileSim_read(secNum*512,pBuf,512);
}

UFAV FileSimWrSct(U32 secNum, const U8* IN pBuf)
{
	return FileSim_write(secNum*512,pBuf,512);
}

⌨️ 快捷键说明

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