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

📄 fat.c

📁 CIRRUS 93XX系列windows mobile 6.0 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "windows.h"
#include "fat.h"

#pragma pack(push,1)
#define MAX_PART 24


static UCHAR  g_dwDevIndex=0;
static DWORD  g_dwPartNum=0;
static DWORD  g_dwVolume =0;

static PARTITION_INFO  g_PartitionInfo[MAX_PART];
static VOLUME_FAT	   g_FatInfo[MAX_PART];
static FILE_DESC       g_FileDesc;
static DWORD			g_bFatCache[SECTOR_SIZE/4];
static DWORD		   g_dwCacheSector=-1;

static DWORD			g_BufCluster[32768/4];

/**********************************************************************************

Functions releated with partition table


//**********************************************************************************/

__inline ISFATSYSTEM( DWORD data)
{
	BOOL bTrue=FALSE;
	
	switch( data  ){

	case 0x4:
	case 0x6:
	case 0xB:
	case 0xC:
	case 0xE:
		bTrue=TRUE;
		break;
	default:
		break;
	}
	return bTrue;
}

#define ISEXTEND(type)     ( type ==0x05  || type ==0x0F  ||  type ==0x85   )


BOOL InitializePartionTable( void  )
{
	int i;
	UCHAR *pPartInDisk;
	DWORD dwExtendStart;
	DWORD dwExtendNum  ;
	DWORD dwBuffer[SECTOR_SIZE/4];
	UCHAR *cBuffer=(PUCHAR)dwBuffer;

	RETAILMSG( DEBUG_TEST,(L"Partition: check buffer %x---%x\r\n",cBuffer,dwBuffer));
	if( !ReadSectors( g_dwDevIndex, 0, 1, cBuffer) )
		return FALSE;

	if( cBuffer[0x1Fe] !=0x55 ||
		cBuffer[0x1FF] !=0xAA 
		)
		return FALSE;

	//check major partitions:

	pPartInDisk= cBuffer+0x1BE;

	for( i=0; i<4; i++ , pPartInDisk+=16 ){

		if( *(pPartInDisk +4)  ) //it's a valid partition
		{
			g_PartitionInfo[g_dwPartNum].dwStartSector=MAKE_DWORD (pPartInDisk +8 );

			g_PartitionInfo[g_dwPartNum].dwSectorNum= MAKE_DWORD (pPartInDisk +12 );
			g_PartitionInfo[g_dwPartNum].dwType =pPartInDisk[4];

			g_PartitionInfo[g_dwPartNum].dwIndex=g_dwPartNum;

			RETAILMSG( DEBUG_TEST,(L"Partition: start %u--%x, num %d, type %d\r\n",
				g_PartitionInfo[g_dwPartNum].dwStartSector,
				g_PartitionInfo[g_dwPartNum].dwStartSector,
				g_PartitionInfo[g_dwPartNum].dwSectorNum,
				g_PartitionInfo[g_dwPartNum].dwType
				));

//			RETAILMSG( DEBUG_TEST,(L"Partition: address %x---%x\r\n",pPartInDisk +8, pPartInDisk +12));

//			if( ISFATSYSTEM( *(pPartInDisk +4) ) )// || ISEXTEND(*(pPartInDisk +4) ) ) 
				g_dwPartNum++;
		}else
			break;
	}

	RETAILMSG( DEBUG_TEST,(L"Partition: major finished \r\n"));
	//Check ones in Extend partition.
	if( ISEXTEND( g_PartitionInfo[g_dwPartNum-1 ].dwType )  )
	{
		RETAILMSG( DEBUG_TEST,(L"Partition: last is ext \r\n"));
		g_dwPartNum--;
		dwExtendStart=g_PartitionInfo[g_dwPartNum].dwStartSector;
		dwExtendNum  =g_PartitionInfo[g_dwPartNum].dwSectorNum;
	}

	while( ISEXTEND( g_PartitionInfo[g_dwPartNum ].dwType ) && g_dwPartNum <24) {

		DWORD dwNextPart= g_PartitionInfo[g_dwPartNum].dwStartSector;

		if( !ReadSectors( g_dwDevIndex, dwNextPart, 1, cBuffer) )
			return FALSE;

		if( cBuffer[0x1Fe] !=0x55 ||
			cBuffer[0x1FF] !=0xAA 
			)
			return FALSE;

		pPartInDisk= cBuffer+0x1BE;


		for( i=0; i<2; i++ , pPartInDisk+=16 ){

			if( *(pPartInDisk +4)  ) //it's a valid partition
			{
				g_PartitionInfo[g_dwPartNum].dwStartSector=MAKE_DWORD (pPartInDisk +8 );// +dwExtendStart;

				g_PartitionInfo[g_dwPartNum].dwSectorNum= MAKE_DWORD (pPartInDisk +12 );
				g_PartitionInfo[g_dwPartNum].dwType =pPartInDisk[4];

				if( !ISEXTEND(*(pPartInDisk +4) ) )
				{
					g_PartitionInfo[g_dwPartNum].dwStartSector+=dwNextPart;

				}else{ //ext

					g_PartitionInfo[g_dwPartNum].dwStartSector+=dwExtendStart;
				}

				RETAILMSG( DEBUG_TEST,(L"Partition in ext: start %u, num %d, type %d, offset %d\r\n",
					g_PartitionInfo[g_dwPartNum].dwStartSector,
					g_PartitionInfo[g_dwPartNum].dwSectorNum,
					g_PartitionInfo[g_dwPartNum].dwType,
					MAKE_DWORD (pPartInDisk +8 )
					));

				g_PartitionInfo[g_dwPartNum].dwIndex=g_dwPartNum;

				if( !ISEXTEND(*(pPartInDisk +4) ) )
					g_dwPartNum++;

			}else
				break;
		}

		if( i==2 )

		if( g_PartitionInfo[g_dwPartNum-1].dwStartSector + g_PartitionInfo[g_dwPartNum-1].dwSectorNum  !=
			g_PartitionInfo[g_dwPartNum].dwStartSector 

			){

			RETAILMSG( DEBUG_TEST,( L"Warning, Partition tabe is invalid\r\n"));
		}

	}

	//dump partion info.
	{
		DWORD i;

		for( i=0; i< g_dwPartNum; i ++ ){

			RETAILMSG( DEBUG_ERROR,(L"Partition info: start %u, num %d, type %d\r\n",
				g_PartitionInfo[i].dwStartSector,
				g_PartitionInfo[i].dwSectorNum,
				g_PartitionInfo[i].dwType
				));
		}
	}

	return TRUE;
}



BOOL PartitionReadDisk( PPARTITION_INFO pInfo, DWORD dwSector, DWORD dwNum, UCHAR* pBuffer)
{
	return ReadSectors( g_dwDevIndex, pInfo->dwStartSector +dwSector , (WORD)dwNum, pBuffer);
}
/**********************************************************************************

Functions releated with FAT file system.


//**********************************************************************************/

BOOL	CheckFAT32Part( PVOLUME_FAT pVolume ,char * pTempBuf )
{
	PFSINFO  pFsInfo = (PFSINFO )(pTempBuf+512);

	if( pFsInfo ->dwLeadSig !=  0x41615252 )
		return FALSE;

	if( pFsInfo->dwStructSig !=0x61417272 )
		return FALSE;

	if(	pFsInfo->dwTrailSig  != 0xAA550000 )
		return FALSE;
/*
	pFsInfo ++;
	if(	pFsInfo->dwTrailSig  != 0xAA550000 )
		return FALSE;
*/
	return TRUE;
}



BOOL	CheckFATValidity( PVOLUME_FAT  pVolume, char *pcBuf )
{
	PBPB_STRUCT		pPbp=(PBPB_STRUCT)pcBuf;
	PFAT32STRUCT    pPbp32;
	PFAT16STRUCT    pPbp16;

	//Following codes implemented exactly following the FAT specification published by Microsoft.
	DWORD  dwRootDirSectors  ,dwFATSize ,dwFirstDataSec;
	DWORD  dwCountofClusters,dwDataSec ,dwTotSec;

	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check Validity entered 0x%x\r\n"),pcBuf));

	pPbp32=(PFAT32STRUCT)(pcBuf+sizeof(BPB_STRUCT));
	pPbp16=(PFAT16STRUCT)(pcBuf+sizeof(BPB_STRUCT));

	if( pPbp->wBPB_BytePerSec==512 ||
		pPbp->wBPB_BytePerSec==1024 ||
		pPbp->wBPB_BytePerSec==2048 ||
		pPbp->wBPB_BytePerSec==4096 
		){

		//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check rrrr ,%x\r\n"),pPbp));
	}else{
		return FALSE;
	}

	if( pPbp->nPBP_SecPerClus == 1  ||
		pPbp->nPBP_SecPerClus == 2  ||
		pPbp->nPBP_SecPerClus == 4  ||
		pPbp->nPBP_SecPerClus == 8  ||
		pPbp->nPBP_SecPerClus == 16  ||
		pPbp->nPBP_SecPerClus == 32  ||
		pPbp->nPBP_SecPerClus == 64  ||
		pPbp->nPBP_SecPerClus == 128
		){

		if( pPbp->wBPB_BytePerSec * pPbp->nPBP_SecPerClus >(32*1024) ) {

			return FALSE;
		}
	}else{

		return FALSE;
	}

	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check 000000000 ,%x\r\n"),pPbp));
	//Now, try to decide the version of the FAT.
	dwRootDirSectors = ((pPbp->wPBP_RootEntryCount* 32)+(pPbp->wBPB_BytePerSec-1)) / pPbp->wBPB_BytePerSec;
	//First, the size of root directory ;
	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check 111111 \r\n")));

	if(pPbp->wPBP_FATSize16!= 0)
		dwFATSize = pPbp->wPBP_FATSize16;
	else
		dwFATSize = pPbp32->dwBPB_FATSize32;

	if(pPbp->wPBP_TotalSector16!= 0)
		dwTotSec = pPbp->wPBP_TotalSector16;
	else
		dwTotSec = pPbp->dwPBP_TotalSector32;

	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check 22222222 \r\n")));

	dwFirstDataSec=(pPbp->wPBP_RsvdSecCnt + (pPbp->nPBP_NumFATs* dwFATSize) + dwRootDirSectors );

	dwDataSec = dwTotSec-dwFirstDataSec;

	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check 333333333 \r\n")));

	dwCountofClusters = dwDataSec / pPbp->nPBP_SecPerClus;

	if(dwCountofClusters < 4085) {

		pVolume->dwVersion=FAT_VERSION12;
		// Volume is FAT12 
		//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  Check Validity FAT12\r\n")));
		return FALSE;
	} else if(dwCountofClusters < 65525) {

		pVolume->dwVersion=FAT_VERSION16;
		// Volume is FAT16 
	} else {

		pVolume->dwVersion=FAT_VERSION32;
	// Volume is FAT32 
	}
	//RETAILMSG( DEBUG_FAT,(TEXT("FAT Mount Disk  FAT file system detect\r\n")));

	if ( pPbp->cBS_JumpRoot[0] ==0xEB ){

		if ( pPbp->cBS_JumpRoot[2] !=0x90 ){

			return FALSE;
		}
	}else if(pPbp->cBS_JumpRoot[0] !=0xE9 ){

		return FALSE;
	}

	/*if( pPbp->wBPB_BytePerSec==512 ||
		pPbp->wBPB_BytePerSec==1024 ||
		pPbp->wBPB_BytePerSec==2048 ||
		pPbp->wBPB_BytePerSec==4096 
		){

		if( pPbp->nPBP_SecPerClus == 1  ||
			pPbp->nPBP_SecPerClus == 2  ||
			pPbp->nPBP_SecPerClus == 4  ||
			pPbp->nPBP_SecPerClus == 8  ||
			pPbp->nPBP_SecPerClus == 16  ||
			pPbp->nPBP_SecPerClus == 32  ||
			pPbp->nPBP_SecPerClus == 64  ||
			pPbp->nPBP_SecPerClus == 128
			){

			if( pPbp->wBPB_BytePerSec * pPbp->nPBP_SecPerClus >(32*1024) ) {

				return FALSE;
			}

		}
	}*/
	if( pPbp->wPBP_RsvdSecCnt ==0 )
		return FALSE;
	if( pVolume->dwVersion ==FAT_VERSION32 ){

		if (pPbp->wPBP_RootEntryCount !=0 )
			return FALSE;

		if( pPbp->wPBP_TotalSector16 !=0 )
			return FALSE;

		if( pPbp->wPBP_FATSize16 !=0 )
			return FALSE;

		if( pPbp->dwPBP_TotalSector32 ==0 )
			return FALSE;

	}else if( pVolume->dwVersion ==FAT_VERSION16 ){

		//if( pPbp->wPBP_TotalSector16 ==0 )
		//	return FALSE;

		if( pPbp->wPBP_FATSize16 ==0 )
			return FALSE;
		//if( pPbp->dwPBP_TotalSector32 !=0 )
		//	return FALSE;

		if( pPbp->wPBP_TotalSector16 ==0 ){

			if( pPbp->dwPBP_TotalSector32 ==0 )
				return FALSE;
		}
	}
//	if( (pcBuf[510] !=0x55) || (pcBuf[511] !=0xAA) )
//		return FALSE;
	//Now, save the volume information.
	//pPbp->wPBP_RsvdSecCnt + (pPbp->nPBP_NumFATs* dwFATSize);

	pVolume->fat_info.dwBytesPerSec= pPbp->wBPB_BytePerSec;
	pVolume->fat_info.dwRsvedSector =pPbp->wPBP_RsvdSecCnt;
	pVolume->fat_info.dwNumFAT		=pPbp->nPBP_NumFATs;
	pVolume->fat_info.dwSecPerCluster=pPbp->nPBP_SecPerClus;

	pVolume->dwFirstDataSec =dwFirstDataSec;
	pVolume->fat_info.dwClusterCount=dwCountofClusters;

	if( pVolume->dwVersion ==FAT_VERSION32 ){
		
		memcpy(pVolume->cLabel,pPbp32->cBS_VolLab, LABEL_SIZE );
		pVolume->cLabel[LABEL_SIZE]=0;	//set the string end.

		pVolume->fat_info.dwRootEntryCount= 0; //it's invalid in FAT32.
		pVolume->fat_info.dwFATSize		 =  pPbp32->dwBPB_FATSize32;
		//pVolume->fat_info.dwTotalSector	 =  pPbp->dwPBP_TotalSector32;
		pVolume->fat_info.dwRootCluster	 =  pPbp32->dwBPB_RootCluster;

		if( !CheckFAT32Part( pVolume ,pcBuf )  ){

			return FALSE;
		}
		pVolume->dwRootDirSec = FIRST_SECTOR_OF_CLUSTER( pVolume,pVolume->fat_info.dwRootCluster);
		pVolume->dwRootDirClusterNum=0;

	}else if( pVolume->dwVersion ==FAT_VERSION16 ){

		//memcpy(pVolume->cLabel,pPbp16->cBS_VolLab, LABEL_SIZE );
		//pVolume->cLabel[LABEL_SIZE]=0;	//set the string end.

		pVolume->fat_info.dwRootEntryCount= pPbp->wPBP_RootEntryCount;
		pVolume->fat_info.dwFATSize		 =  pPbp->wPBP_FATSize16;
		//pVolume->fat_info.dwTotalSector	 =  pPbp->wPBP_TotalSector16;
		pVolume->fat_info.dwRootCluster	 =  0;	//Braden modified 2003-4-29...only for testing.

		pVolume->dwRootDirSec = pPbp->wPBP_RsvdSecCnt + (pPbp->nPBP_NumFATs* dwFATSize);

		pVolume->dwRootDirClusterNum= dwRootDirSectors/ pVolume->fat_info.dwSecPerCluster;

		if( dwRootDirSectors% pVolume->fat_info.dwSecPerCluster ){

			return FALSE;
		}
	}

	pVolume->fat_info.dwClusterCount  += pVolume->dwRootDirClusterNum;

	if( pPbp->dwPBP_TotalSector32 )
		pVolume->fat_info.dwTotalSector	 =  pPbp->dwPBP_TotalSector32;
	else
		pVolume->fat_info.dwTotalSector	 =  pPbp->wPBP_TotalSector16;

	return TRUE;
}



BOOL LoadFATFileSystem(  PPARTITION_INFO pInfoPart, PVOLUME_FAT pVolume)
{
	UCHAR pBuffer[3*SECTOR_SIZE];

	if( !pBuffer )
		return FALSE;

	if( !PartitionReadDisk( pInfoPart, 0, 3, pBuffer) ){

		goto Load_failed;
	}

	if( !CheckFATValidity( pVolume, (char*)pBuffer )  )
		goto Load_failed;

	
	if( pVolume->fat_info.dwTotalSector > pInfoPart->dwSectorNum ) 
		RETAILMSG( DEBUG_ERROR,(L"Error, partition info is error\r\n"));


	return TRUE;

Load_failed:

	return FALSE;
}



BOOL InitializeFATSystem( void  )
{
	DWORD i;

	for( i=0; i< g_dwPartNum; i ++ ){

		if( ISFATSYSTEM( g_PartitionInfo[ i ].dwType )  ){

			if( LoadFATFileSystem( &g_PartitionInfo[i] , &g_FatInfo[g_dwVolume] ) ){

				g_FatInfo[g_dwVolume].pPartInfo= &g_PartitionInfo[i];
				g_dwVolume++;
			}
		}
	}

	return TRUE;
}


/**********************************************************************************

Functions releated with search and find file.


//**********************************************************************************/

//Caculate where is the entry in the FAT table for a specific Cluster.
BOOL  GetClusterInFAT( PVOLUME_FAT pVolume , DWORD dwCluster ,DWORD * pdwSectorNum, DWORD * pdwOffsetInSec)
{
	DWORD	dwOffset;

	if( dwCluster <  pVolume->dwRootDirClusterNum +2)
		return FALSE;

	if( dwCluster > pVolume->fat_info.dwClusterCount )
		return FALSE;

	dwCluster-=pVolume->dwRootDirClusterNum;

	if( pVolume->dwVersion ==FAT_VERSION16  ){

		dwOffset=dwCluster*2;
	}else if ( pVolume->dwVersion ==FAT_VERSION32  ){

⌨️ 快捷键说明

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