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

📄 fat.cpp

📁 fat file system api in VC
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	return TRUE;
}

INT FAT::GetFirstSecOfClu(INT ClusterNum)
{
	INT FirstSec=BPB.ReservedSectors+BPB.FatNum*BPB.SectorsPerFAT
		 +(ClusterNum-2)*BPB.SectorsPerCluster;
	
	return FirstSec;
}

BOOL FAT::GetEntryAddr(CHAR *sPath, DIRINCLU &DirEnt)
{
	TRACE("In GetEntryAddr: %d\n",strlen(sPath));
    if(IsLongFileName(sPath))
	{
		GetShortPathName((char*)sPath,(char*)sPath,strlen(sPath));
	}
	PATHINFO PathInfo;
	PathInfo.nLayer=-1;
	PathInfo.pNext=NULL;

	if(!BreakPath(sPath,PathInfo))
	{
		return FALSE;
	}

    CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
	INT  ClusterNum=BPB.RootEntry;
	if(!ClusterBuffer)
	{
		return FALSE;
	}
	if(!ReadCluster(ClusterNum,ClusterBuffer))
	{
		return FALSE;
	}

	PATHINFO *pCur=PathInfo.pNext;//the first layer is "M:",need not to be found.
	DIRINCLU EntInClu;
	Directory_FAT EntryContent;
	while(pCur)
	{
        while(!GetEntryAddr(ClusterNum,ClusterBuffer,(CHAR*)pCur->ByteArray.GetData(),EntInClu))
		{
		    ClusterNum=GetNextCluster(ClusterNum);
			if(ClusterNum==-1)//indicates reach the end of this cluster
			{
				return FALSE;
			}
			if(!ReadCluster(ClusterNum,ClusterBuffer))
			{
				return FALSE;
			}
		}
        if(!GetEntryContent(ClusterBuffer,EntInClu.DirOffset,EntryContent))
		{
			return FALSE;
		}
		ClusterNum=EntryContent.StartCluster;
		if(!ReadCluster(ClusterNum,ClusterBuffer))
		{
			return FALSE;
		}

		pCur=pCur->pNext;
	}

	DirEnt.ClusterNum=EntInClu.ClusterNum;
	DirEnt.DirOffset=EntInClu.DirOffset;

	return TRUE;
}

BOOL FAT::BreakPath(const CHAR *sPath, PATHINFO &PathInfo)
{
	int j=0,Layer=0;
	PATHINFO *p=&PathInfo;
    TRACE("%d\n",strlen(sPath));
    for(int i=0;i<strlen(sPath);i++)
	{
		if(sPath[i]==0x5C)//0x5C='\'
		{
            if(!CopyByteStr(p->ByteArray,sPath,j,i))
			{
				return FALSE;
			}
			j=i+1;
			p->nLayer=Layer;
			p->pNext=new PATHINFO;
			if(!p->pNext)
			{
				return FALSE;
			}
			p->pNext->nLayer=0;
			p->pNext->pNext=NULL;

            p=p->pNext;
			Layer++;
		}
	}
	if(!CopyByteStr(p->ByteArray,sPath,j,i))
	{
		return FALSE;
	}
	p->nLayer=Layer;
	
	return TRUE;
}

BOOL FAT::IsLongFileName(const CHAR *sPath)
{
	PATHINFO PathInfo,*p;
	BreakPath(sPath,PathInfo);

	for(p=&PathInfo;	p;	p=p->pNext)
	{
		CString temp(p->ByteArray.GetData());
		if(int PointPos=temp.Find("."))
		{
			if(PointPos>7)
			{
				return FALSE;
			}
			if(p->ByteArray.GetSize()-(PointPos+1)>3)
			{
				return FALSE;
			}
		}
		else if(p->ByteArray.GetSize()>8)
		{
			DeletePathInfo(PathInfo);
			return TRUE;
		}
	}
	DeletePathInfo(PathInfo);

    return FALSE;
}

BOOL FAT::CopyByteStr(CByteArray &Destination, const CHAR *Source,	INT BeginIndex,	INT EndIndex)
{
    if(sizeof(Source)<=0)
	{
		return FALSE;
	}
	if(EndIndex<BeginIndex)
	{
		return FALSE;
	}
	if(BeginIndex>=strlen(Source)&&EndIndex>=strlen(Source))
	{
		return FALSE;
	}
	
	for(int i=BeginIndex;	i<EndIndex;	  i++)
	{
		Destination.SetAtGrow(i-BeginIndex,Source[i]);
	}
	Destination.SetAtGrow(i-BeginIndex,0);

	return TRUE;
}

BOOL FAT::DeletePathInfo(PATHINFO	&PathInfo)
{
	PATHINFO *p=PathInfo.pNext,*q=PathInfo.pNext->pNext;

	while(q)
	{
		delete p;
		p=q;
		q=p->pNext;
	}
	delete p;

	return TRUE;
}

BOOL FAT::GetEntryAddr(INT ClusterNum, CHAR* ClusterBuffer, CHAR* FileName, DIRINCLU &DirInClu)
{
    int EntryIndex=0;
	Directory_FAT EntryContent;
	while(EntryIndex<GetClusterSize()/32)
	{
		GetEntryContent(ClusterBuffer,EntryIndex,EntryContent);
		if(IsFileNameEqual(FileName,EntryContent))
		{
		    DirInClu.ClusterNum=ClusterNum;
			DirInClu.DirOffset=EntryIndex;
			return TRUE;
		}
		EntryIndex++;
	}

	return FALSE;
}

INT FAT::GetClusterSize()
{
    return BPB.BytesPerSector*BPB.SectorsPerCluster;
}

BOOL FAT::GetEntryContent(CHAR *ClusterBuffer, INT EntryIndex, Directory_FAT &EntryContent)
{
	if(sizeof(ClusterBuffer)<=0)
	{
		return FALSE;
	}
	if(EntryIndex<0||EntryIndex>=GetClusterSize()/32)
	{
		return FALSE;
	}

	int Ent=EntryIndex*32;

	CopyElements(EntryContent.FileName,&ClusterBuffer[Ent],8);
	EntryContent.FileName[8]=0;
	CopyElements(EntryContent.ExtName,&ClusterBuffer[Ent+0x08],3);
	EntryContent.ExtName[3]=0;

	EntryContent.Archives=0;
	EntryContent.Directory=0;
	EntryContent.Hidden=0;
	EntryContent.ReadOnly=0;
	EntryContent.System=0;
	EntryContent.Volume=0;
	if(ClusterBuffer[Ent+0xB]&1)
	{
		EntryContent.ReadOnly=1;
	}
	if(ClusterBuffer[Ent+0xB]&2)
	{
		EntryContent.Hidden=1;
	}
	if(ClusterBuffer[Ent+0xB]&4)
	{
		EntryContent.System=1;
	}
	if(ClusterBuffer[Ent+0xB]&8)
	{
		EntryContent.Volume=1;
	}
	if(ClusterBuffer[Ent+0xB]&16)
	{
		EntryContent.Directory=1;
	}
	if(ClusterBuffer[Ent+0xB]&32)
	{
		EntryContent.Archives=1;
	}

	CopyElements(EntryContent.Reserved,&ClusterBuffer[Ent+0xC],sizeof(EntryContent.Reserved));
    EntryContent.Reserved[10]=0;

	int temp=(unsigned char)ClusterBuffer[Ent+0x16+1]*0x100
		    +(unsigned char)ClusterBuffer[Ent+0x16];
	EntryContent.FileCreTime.Hour=temp/2048;
	EntryContent.FileCreTime.Min=(temp%2048)/32;
	EntryContent.FileCreTime.Sec=((temp%2048)%32)*2-2;

	TRACE("\n%x,%x",ClusterBuffer[0x19],ClusterBuffer[0x18]);
    temp=(unsigned char)ClusterBuffer[Ent+0x18+1]*0x100+
		 (unsigned char)ClusterBuffer[Ent+0x18];
	EntryContent.FileCreDate.Year=temp/512+1980;
	EntryContent.FileCreDate.Mon=(temp%512)/32;
	EntryContent.FileCreDate.Day=(temp%512)%32;

	EntryContent.StartCluster=(unsigned char)ClusterBuffer[Ent+0x1A+1]*0x100+
		          (unsigned char)ClusterBuffer[Ent+0x1A];

	EntryContent.FileLength=(unsigned char)ClusterBuffer[Ent+0x1C+3]*0x100*0x100*0x100
		+(unsigned char)ClusterBuffer[Ent+0x1C+2]*0x100*0x100+
		(unsigned char)ClusterBuffer[Ent+0x1C+1]*0x100+(unsigned char)ClusterBuffer[Ent+0x1C];

	return TRUE;
}

INT FAT::GetNextCluster(INT CurCluster)
{
	INT SectorNum=BPB.ReservedSectors+CurCluster/128;//128 Clusters take one sector FAT
	ABS_SEC_BUF buffer;
	buffer.IsValid=-1;

	if(!ReadSector(SectorNum,buffer))
	{
		return FALSE;
	}
    INT	Offset=(CurCluster%128)*4;

	INT n= (buffer.Data[Offset+3]&0x0F)*0x100*0x100*0x100
		   +buffer.Data[Offset+2]*0x100*0x100
		   +buffer.Data[Offset+1]*0x100
		   +buffer.Data[Offset];

	if(n==0xFFFFFFF)//到达文件末尾
	{
		return -1;
	}
	return n;
}

BOOL FAT::IsFileNameEqual(CHAR *FileName, Directory_FAT EntryContent)
{//FileName represents the whole file name, FilName the main name, and ExtName the extension name. 
	CHAR FilName[9]="        ",ExtName[4]="   ";
	if(!SplitFileName(FileName,FilName,ExtName))
	{
		return FALSE;
	}
	strupr(FilName);
	strupr(ExtName);
	strupr(EntryContent.FileName);
	strupr(EntryContent.ExtName);

	if((strcmp(FilName,EntryContent.FileName)!=0))
	{
		return FALSE;
	}
	if(strcmp(ExtName,EntryContent.ExtName)!=0)
	{
		return FALSE;
	}

	return TRUE;
}

BOOL FAT::SplitFileName(const CHAR* FileName,CHAR* FilName, CHAR* ExtName)
{
    int PointPos;
	for(int i=0;	i<strlen(FileName);	i++)
	{
		FilName[i]=FileName[i];
		if(FileName[i]=='.')
		{
			PointPos=i;
			CopyElements(ExtName,&FileName[PointPos+1],3);
			break;
		}
	}
	if(i<8)
	{
		while(i<8)
		{
			FilName[i]=' ';
			i++;
		}
	}

	return TRUE;
}

BOOL FAT::SetEntryContent(CHAR *sPath, Directory_FAT EntryContent)
{
	DIRINCLU DirEnt;
	if(!GetEntryAddr(sPath,DirEnt))
	{
		return FALSE;
	}
	CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
	if(ClusterBuffer)
	{
		if(!ReadCluster(DirEnt.ClusterNum,ClusterBuffer))
		{
			return FALSE;
		}

		strcpy(&ClusterBuffer[DirEnt.DirOffset*32],EntryContent.FileName);
		strcpy(&ClusterBuffer[DirEnt.DirOffset*32+0x08],EntryContent.ExtName);

		if(EntryContent.ReadOnly)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=1;
		}
		if(EntryContent.Hidden)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=2;
		}
		if(EntryContent.System)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=4;
		}
		if(EntryContent.Volume)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=8;
		}
		if(EntryContent.Directory)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=16;
		}
		if(EntryContent.Archives)
		{
			ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=32;
		}

		strcpy(&ClusterBuffer[DirEnt.DirOffset*32+0xC],EntryContent.Reserved);

		WORD Time,Date;
		Time=EntryContent.FileCreTime.Hour*2048+EntryContent.FileCreTime.Min*32
			        +EntryContent.FileCreTime.Sec/2;
		ClusterBuffer[DirEnt.DirOffset*32+0x16]=Time%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x16+1]=Time/0x100;
		
		Date=(EntryContent.FileCreDate.Year-1980)*512+EntryContent.FileCreDate.Mon*32
			   +EntryContent.FileCreDate.Day;
		ClusterBuffer[DirEnt.DirOffset*32+0x18]=Date%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x18+1]=Date/0x100;

		ClusterBuffer[DirEnt.DirOffset*32+0x1A]=EntryContent.StartCluster%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x1A+1]=EntryContent.StartCluster/0x100;

		ClusterBuffer[DirEnt.DirOffset*32+0x1C]=EntryContent.FileLength%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x1C+1]=(EntryContent.FileLength/0x100)%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x1C+2]=(EntryContent.FileLength/0x10000)%0x100;
		ClusterBuffer[DirEnt.DirOffset*32+0x1C+3]=EntryContent.FileLength/0x1000000;
	}

	if(!WriteCluster(DirEnt.ClusterNum,ClusterBuffer))
	{
		return FALSE;
	}

	delete[] ClusterBuffer;
	return TRUE;
}

BOOL FAT::GetEntryContent(CHAR *sPath, Directory_FAT &EntryContent)
{
	DIRINCLU DirEnt;
	if(!GetEntryAddr(sPath,DirEnt))
	{
		return FALSE;
	}
	CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
	if(!ClusterBuffer)
	{
		return FALSE;
	}
    if(!ReadCluster(DirEnt.ClusterNum,ClusterBuffer))
	{
		return FALSE;
	}
    if(!GetEntryContent(ClusterBuffer,DirEnt.DirOffset,EntryContent))
	{
		return FALSE;
	}

	delete[] ClusterBuffer;
	return TRUE;
}

⌨️ 快捷键说明

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