📄 fat.cpp
字号:
// FAT.cpp: implementation of the FAT class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxtempl.h>
#include "FS.h"
#include "FAT.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
FAT::FAT(LPCTSTR pVolumeLab)
{
BPB.BytesPerSector=512;
char pVolTemp[3];
pVolTemp[0]=pVolumeLab[0];
pVolTemp[1]=pVolumeLab[1];
pVolTemp[2]=0;
pVolume=pVolTemp;
if(!GetDevice(pVolume))
{
return;
}
if(!GetSpecificBPB(BPB))
{
return;
}
}
FAT::~FAT()
{
if(m_hDevice!=INVALID_HANDLE_VALUE)//关闭设备句柄
{
CloseHandle(m_hDevice);
}
}
BOOL FAT::GetDevice(LPCTSTR lpRoot)
{
CHAR FileSysType[10];//存储文件系统类型
ASSERT(GetVolumeInformation(lpRoot,NULL,0,NULL,0,NULL,FileSysType,sizeof(FileSysType)));
if(!strcmp(FileSysType,"FAT32"))//检测文件系统是否是 FAT32
{
m_hDevice=CreateFile(CString("\\\\.\\") + lpRoot,//获得设备句柄
GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL);
if(m_hDevice==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"获得设备句柄失败!","错误",MB_ICONSTOP);
CloseHandle(m_hDevice);
return FALSE;
}
}
else
{//当文件系统不是FAT32时
CString sMessage;
sMessage.Format("你当前所选择的不是FAT32文件系统的磁盘,操作中止! ");
MessageBox(NULL,sMessage,"错误",MB_OK);
}
return TRUE;
}
BOOL FAT::GetSpecificBPB(BPB_FAT &bpb)
{
ABS_SEC_BUF buffer;
buffer.IsValid=0;
if(!ReadSector(0,buffer))
{
return FALSE;
}
if(buffer.IsValid){
bpb.BigTotalSectors=buffer.Data[0x20+3]*0x100*0x100*0x100
+buffer.Data[0x20+2]*0x100*0x100+buffer.Data[0x20+1]*0x100+buffer.Data[0x20];
bpb.boot_rec_sig=-1; /*含义未知*/
CopyElements(bpb.BootCode,&buffer.Data[0x3E],sizeof(bpb.BootCode));
bpb.BytesPerSector=buffer.Data[0x0B+1]*0x100+buffer.Data[0x0B];
bpb.Drive=buffer.Data[0x24];
CopyElements(bpb.FileSys_ID,(char*)&buffer.Data[0x36],sizeof(bpb.FileSys_ID));
bpb.Head=-1;
bpb.Heads=buffer.Data[0x1A+1]*0x100+buffer.Data[0x1A];
bpb.HiddenSectorNum=buffer.Data[0x0E+1]*0x100+buffer.Data[0x0E];
CopyElements((char*)bpb.JMPCode,(char*)&buffer.Data[0x00],sizeof(bpb.JMPCode));
CopyElements((char*)bpb.Label,(char*)&buffer.Data[0x2B],sizeof(bpb.Label));
bpb.Media=(MediaType)(buffer.Data[0x15]);
bpb.FatNum=buffer.Data[0x10];
bpb.ReservedSectors=buffer.Data[0x0E+1]*0x100+buffer.Data[0x0E];
bpb.RootEntry=buffer.Data[0x2F]*0x100*0x100*0x100+buffer.Data[0x2E]*0x100*0x100
+buffer.Data[0x2D]*0x100+buffer.Data[0x2C];
bpb.SectorsPerCluster=buffer.Data[0x0D];
bpb.SectorsPerFAT=buffer.Data[0x24+3]*0x100*0x100*0x100
+buffer.Data[0x24+2]*0x100*0x100+buffer.Data[0x24+1]*0x100+buffer.Data[0x24];
bpb.SectorsPerTrack=buffer.Data[0x18+1]*0x100+buffer.Data[0x18];
CopyElements((char*)bpb.FileSys_ID,(char*)&buffer.Data[0x03],sizeof(bpb.System_ID));
bpb.TotalSectors=buffer.Data[0x13+1]*0x100+buffer.Data[0x13];
bpb.Vol_Serial_NoL=buffer.Data[0x27+1]*0x100+buffer.Data[0x27];
bpb.Vol_Serial_NoH=0; /*待定*/
}//if
return TRUE;
}
BOOL FAT::GetDPB(DPB &dpb)
{
dpb.BytePerSec=BPB.BytesPerSector;
dpb.DriveNo=pVolume[0];
dpb.FirstDataSec=0; /*待定*/
dpb.FirstFATSec=BPB.ReservedSectors;
dpb.FirstFreeClu=0; /*待定*/
dpb.FreeClu=0; /*待定*/
dpb.LastClu=0; /*待定*/
dpb.MediaID=BPB.Media;
dpb.FATNum=BPB.FatNum;
dpb.PhyDrive=BPB.Drive;
dpb.RelativeSectors=0; /*待定*/
dpb.RootEntryNum=0; /*待定*/
dpb.RootStartSec=BPB.RootEntry;
dpb.SecPerClu=BPB.SectorsPerCluster;
dpb.SecPreFAT=BPB.SectorsPerFAT;
dpb.SectorsPerTrack=BPB.SectorsPerTrack;
dpb.TotalSectors=BPB.BigTotalSectors+BPB.TotalSectors;//one of them is 0
return TRUE;
}
BOOL FAT::ReadSector(INT SectorNum,ABS_SEC_BUF &buffer)
{
if(SectorNum<0)
{
AfxMessageBox("扇区号必须大于0");
return FALSE;
}
INT StartAddress=SectorNum*BPB.BytesPerSector;
DWORD BytesRead;
if(SetFilePointer(m_hDevice,StartAddress,0,FILE_BEGIN)== 0xFFFFFFFF)
{//将指针移到指定位置处
return FALSE;
}
CHAR Buffer[512];
if(!ReadFile(m_hDevice,Buffer,BPB.BytesPerSector,&BytesRead,NULL))
{
TRACE("ReadFile Error: %d\n",GetLastError());
return FALSE;
}
else
{
CopyElements((char*)buffer.Data,Buffer,512);
buffer.SectorNum=SectorNum;
buffer.IsValid=1;
}
return TRUE;
}
BOOL FAT::ReadFAT(INT SectorNum, FAT_BUF &buffer)
{
ABS_SEC_BUF Buffer;
Buffer.IsValid=0;
if(!ReadSector(SectorNum,Buffer))
{
return FALSE;
}
if(Buffer.IsValid)
{
for(int i=0; i<sizeof(buffer.Data)/4; i++)
{
buffer.Data[i]=Buffer.Data[4*i+3]*0x100*0x100*0x100
+Buffer.Data[4*i+2]*0x100*0x100+Buffer.Data[4*i+1]*0x100+Buffer.Data[4*i];
}
buffer.IsValid=Buffer.IsValid;
buffer.SectorNum=Buffer.SectorNum;
}
return TRUE;
}
BOOL FAT::ReadSector(INT SectorNum, WORD_SEC_BUF &buffer)
{
ABS_SEC_BUF Buffer;
Buffer.IsValid=0;
if(!ReadSector(SectorNum,Buffer))
{
return FALSE;
}
if(Buffer.IsValid)
{
for(int i=0; i<sizeof(buffer.Data)/2; i++)
{
buffer.Data[i]=Buffer.Data[2*i+1]*0x100+Buffer.Data[2*i];
}
buffer.IsValid=Buffer.IsValid;
buffer.SectorNum=Buffer.SectorNum;
}
return TRUE;
}
BOOL FAT::WriteSector(INT SectorNum, ABS_SEC_BUF &buffer)
{
if(SectorNum<0)
{
AfxMessageBox("扇区号必须大于0");
return FALSE;
}
INT StartAddress=SectorNum*BPB.BytesPerSector;
DWORD BytesRead;
if(SetFilePointer(m_hDevice,StartAddress,0,FILE_BEGIN)== 0xFFFFFFFF)
{//将指针移到指定位置处
return FALSE;
}
if(!buffer.IsValid)
{
AfxMessageBox("数据无效!");
return FALSE;
}
CHAR Buffer[512];
CopyElements((char*)Buffer,(char*)buffer.Data,512);
if(!WriteFile(m_hDevice,Buffer,BPB.BytesPerSector,&BytesRead,NULL))
{
return FALSE;
}
return TRUE;
}
BOOL FAT::WriteFAT(INT SectorNum, FAT_BUF &buffer)
{
if(SectorNum<0)
{
AfxMessageBox("扇区号必须大于0");
return FALSE;
}
INT StartAddress=SectorNum*BPB.BytesPerSector;
DWORD BytesRead;
if(SetFilePointer(m_hDevice,StartAddress,0,FILE_BEGIN)== 0xFFFFFFFF)
{//将指针移到指定位置处
return FALSE;
}
if(!buffer.IsValid)
{
AfxMessageBox("数据无效!");
return FALSE;
}
CHAR Buffer[512];
CopyElements((char*)buffer.Data,Buffer,512);
if(!WriteFile(m_hDevice,Buffer,BPB.BytesPerSector,&BytesRead,NULL))
{
return FALSE;
}
return TRUE;
}
BOOL FAT::WriteSector(INT SectorNum, WORD_SEC_BUF &buffer)
{
if(SectorNum<0)
{
AfxMessageBox("扇区号必须大于0");
return FALSE;
}
INT StartAddress=SectorNum*BPB.BytesPerSector;
DWORD BytesRead;
if(SetFilePointer(m_hDevice,StartAddress,0,FILE_BEGIN)== 0xFFFFFFFF)
{//将指针移到指定位置处
return FALSE;
}
if(!buffer.IsValid)
{
AfxMessageBox("数据无效!");
return FALSE;
}
CHAR Buffer[512];
CopyElements((char*)buffer.Data,Buffer,512);
if(!WriteFile(m_hDevice,Buffer,BPB.BytesPerSector,&BytesRead,NULL))
{
return FALSE;
}
return TRUE;
}
BOOL FAT::ReadCluster(INT ClusterNum, CHAR *buffer)
{
if(ClusterNum<0)
{
AfxMessageBox("簇号必须大于0");
return FALSE;
}
INT SectorNum=GetFirstSecOfClu(ClusterNum);
int i=0;
ABS_SEC_BUF Buffer;
Buffer.IsValid=0;
while(i<BPB.SectorsPerCluster)
{
ReadSector(SectorNum,Buffer);
if(Buffer.IsValid)
{
CopyElements(&buffer[BPB.BytesPerSector*i],(char*)(Buffer.Data),512);
i++;
SectorNum++;
Buffer.IsValid=0;
}
else
{
return FALSE;
}
}
return TRUE;
}
BOOL FAT::ReadCluster(INT ClusterNum, WORD *buffer)
{
if(ClusterNum<0)
{
AfxMessageBox("簇号必须大于0");
return FALSE;
}
INT SectorNum=GetFirstSecOfClu(ClusterNum);
int i=0;
WORD_SEC_BUF Buffer;
Buffer.IsValid=0;
while(i<BPB.SectorsPerCluster)
{
ReadSector(SectorNum,Buffer);
if(Buffer.IsValid)
{
CopyElements((WORD*)buffer[BPB.BytesPerSector+i],(WORD*)Buffer.Data,(BPB.BytesPerSector)/2);
i++;
SectorNum++;
Buffer.IsValid=0;
}
else
{
return FALSE;
}
}
return TRUE;
}
BOOL FAT::WriteCluster(INT ClusterNum,CHAR *buffer)
{
if(ClusterNum<0)
{
AfxMessageBox("簇号必须大于0");
return FALSE;
}
INT SectorNum=GetFirstSecOfClu(ClusterNum);
ABS_SEC_BUF Buffer;
Buffer.IsValid=0;
int i=0;
while(i<BPB.SectorsPerCluster)
{
CopyElements((CHAR*)Buffer.Data,(CHAR*)&buffer[BPB.BytesPerSector*i],BPB.BytesPerSector);
Buffer.IsValid=1;
Buffer.SectorNum=SectorNum;
if(!WriteSector(SectorNum,Buffer))
{
return FALSE;
}
i++;
SectorNum++;
}
return TRUE;
}
BOOL FAT::WriteCluster(INT ClusterNum,WORD *buffer)
{
if(ClusterNum<0)
{
AfxMessageBox("簇号必须大于0");
return FALSE;
}
INT SectorNum=GetFirstSecOfClu(ClusterNum);
WORD_SEC_BUF Buffer;
Buffer.IsValid=0;
int i=0;
while(i<BPB.SectorsPerCluster)
{
for(int j=0;j<(BPB.BytesPerSector)/2;j++)
{
Buffer.Data[j]=buffer[BPB.BytesPerSector*i+2*j+1]*0x100
+buffer[BPB.BytesPerSector*i+2*j];
}
Buffer.IsValid=1;
Buffer.SectorNum=SectorNum;
if(!WriteSector(SectorNum,Buffer))
{
return FALSE;
}
i++;
SectorNum++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -