📄 filesim.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 + -