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

📄 filesim.c

📁 一个SD卡和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","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));
	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 + -