📄 fat.c
字号:
dwOffset=dwCluster*4;
}
*pdwSectorNum = dwOffset/pVolume->fat_info.dwBytesPerSec + pVolume->fat_info.dwRsvedSector;
*pdwOffsetInSec= dwOffset % pVolume->fat_info.dwBytesPerSec;
return TRUE;
}
DWORD FetchClusEntryVal( PVOLUME_FAT pVolume, char *pcSecBuff, DWORD dwOffsetInSec )
{
DWORD dwFATClusEntryVal;
if( pVolume->dwVersion ==FAT_VERSION16 ){
dwFATClusEntryVal = *((WORD *) &pcSecBuff[dwOffsetInSec]);
if( dwFATClusEntryVal == FAT_CLUSTER_EOC16 )
return dwFATClusEntryVal;
}else{
dwFATClusEntryVal = (*((DWORD *) &pcSecBuff[dwOffsetInSec])) & 0x0FFFFFFF;
if( dwFATClusEntryVal == FAT_CLUSTER_EOC ){
RETAILMSG( DEBUG_ERROR,(L"FetchClusEntryVal Last cluster reached\r\n"));
return dwFATClusEntryVal;
}
}
//return dwFATClusEntryVal ;
//Modified by Braden,2003-4-30... the adjust value for FAT16 root dir cluster number should be plused,
if(dwFATClusEntryVal == 0 )
return 0;
return dwFATClusEntryVal +pVolume->dwRootDirClusterNum;
}
DWORD GetNextCluster( PVOLUME_FAT pFatVol, DWORD dwCurCluster )
{
DWORD dwSector;
DWORD dwOffset;
DWORD dwClus;
if( dwCurCluster < pFatVol->dwRootDirClusterNum ) //FAT 16, in root directory
return dwCurCluster +1 ;
else if( dwCurCluster >= pFatVol->dwRootDirClusterNum +2 ){ //FAT32
if(! GetClusterInFAT( pFatVol, dwCurCluster, &dwSector, &dwOffset) ){
RETAILMSG( DEBUG_ERROR,(L"GetNextCluster GetClusterInFAT failed\r\n"));
return -1;
}
if( g_dwCacheSector != pFatVol->pPartInfo->dwStartSector + dwSector ){
PartitionReadDisk( pFatVol->pPartInfo,
dwSector , 1, (PUCHAR)g_bFatCache );
g_dwCacheSector = pFatVol->pPartInfo->dwStartSector + dwSector;
}
dwClus= FetchClusEntryVal( pFatVol,(PUCHAR)g_bFatCache,dwOffset);
if( dwClus==0 ){
RETAILMSG( DEBUG_ERROR,(L"GetNextCluster FetchClusEntryVal failed\r\n"));
dwClus=-1;
}
return dwClus;
}else{
RETAILMSG( DEBUG_ERROR,(L"GetNextCluster general error\r\n"));
return -1;
}
}
unsigned char ShortNameCheckSum (unsigned char *pFcbName)
{
short FcbNameLen;
unsigned char Sum;
Sum =0;
for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) {
// NOTE: The operation is an unsigned char rotate right
Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++;
}
return (Sum);
}
void CopyShortName( TCHAR * cName, PDIR_ENTRY pDirEntry )
{
int i ,iMinNull=8;
BOOL bExtend=FALSE;
for(i=0; i< 8; i++ ){
cName[i]=pDirEntry->cShortName[i];
}
// memcpy( cName, pDirEntry->cShortName,8 );
for(i=1; i<=8; i++ ){
if( cName[8-i] ==' ' ){
cName[8-i]=0;
iMinNull=8-i;
}else{
break;
}
}
for( i=0; i<3 ; i++ ){
if( pDirEntry->cShortName[8+i] !=' '){
cName[iMinNull+1+i]= pDirEntry->cShortName[8+i];
bExtend=TRUE;
}else{
cName[iMinNull+1+i]=0;
}
}
cName[iMinNull+1+i]=0;
if( bExtend ){
cName[iMinNull]='.';
}else{
cName[iMinNull]=0;
}
}
/*
static void mywcstombs( char * dst, WCHAR * src, int len )
{
int i;
for(i=0; i< len && *src; i++ ){
*dst++= (char)*src++;
}
}
*/
BOOL ReadCluster(PVOLUME_FAT pVol, DWORD dwCluster, PUCHAR pBuf,DWORD dwBufSize)
{
DWORD dwSector;
START_SETOR_OF_CLUSTER(dwSector,pVol, dwCluster);
if( dwSector ==-1)
return FALSE;
return PartitionReadDisk( pVol->pPartInfo, dwSector , pVol->fat_info.dwSecPerCluster, pBuf );
}
DWORD GetFileInfo( PDIR_ENTRY pDirEntry, DWORD dwMaxBuf, PFILE_DESC pFindData, PDIR_ENTRY_FIND pEntry_Find )
{
DWORD dwDirPassed=0;
PLONG_NAME_ENTRY pLongEntry=(PLONG_NAME_ENTRY)pDirEntry;
DWORD dwCurLongDirIndex;
DWORD i;
PUCHAR pTemp=(PUCHAR)pEntry_Find->csName;
for( i=0;(DWORD)pDirEntry<dwMaxBuf; i++ , pDirEntry++ , pLongEntry++ ){
if( pLongEntry->cNameOrder ==DIR_ENTRY_FREE ){
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo,, FREE entry found\r\n")));
continue;
}else if( pLongEntry->cNameOrder == DIR_ENTRY_EOF){ //no more files.
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo,, NO MORE FILE\r\n")));
//SetLastError( ERROR_NO_MORE_FILES);
return -1;
}else if( pLongEntry->cAttr == FILE_ATTR_LONG_NAME ) {
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo,, LONG NAME\r\n")));
if( (pLongEntry->cNameOrder & LAST_LONG_ENTRY )== LAST_LONG_ENTRY ) { // the last long name recorder.
dwCurLongDirIndex= (pLongEntry ->cNameOrder & ~LAST_LONG_ENTRY ) -1;
if( dwCurLongDirIndex > MAX_LONG_NAME_ENTRY ) {//this folder take a invalid recorder, maybe it's damaged.
pEntry_Find->bValid=FALSE;
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo, 000000000000\r\n")));
continue;
}
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY , pLongEntry->cLongName1 ,10);
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +10, pLongEntry->cLongName2 ,12);
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +22, pLongEntry->cLongName3 ,4);
pTemp[ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +26]=0;
pTemp[ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +27]=0;
{
int k;
WORD *pT=(WORD*)&pEntry_Find->csName[ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY];
for( k=0; k<26;k++ ,pT++ ){
if( *pT==0xFFFF )
*pT=0;
}
}
pEntry_Find->dwCurEntryIndex=dwCurLongDirIndex;
pEntry_Find->cChecksum =pLongEntry->cChecksum;
pEntry_Find->bValid =TRUE;
//pEntry_Find->dwLongNameOffset= pEntry_Find->dwLongNameOffset+i;
//pEntry_Find->dwLongNameCluster=dwCluster;
}else if( pLongEntry->cNameOrder < MAX_LONG_NAME_ENTRY ){
if( (DWORD)(pLongEntry->cNameOrder ) != pEntry_Find->dwCurEntryIndex || pEntry_Find->bValid ==FALSE){
pEntry_Find->bValid=FALSE;
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo, 1111111111\r\n")));
continue;
}
dwCurLongDirIndex= pLongEntry->cNameOrder-1;
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY , pLongEntry->cLongName1 ,10);
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +10, pLongEntry->cLongName2 ,12);
memcpy(pTemp+ dwCurLongDirIndex * NAME_SIZE_ONE_ENTRY +22, pLongEntry->cLongName3 ,4);
pEntry_Find->dwCurEntryIndex=pLongEntry->cNameOrder-1;
if( pEntry_Find->cChecksum != pLongEntry->cChecksum ){
pEntry_Find->bValid=FALSE;
}
}else{
pEntry_Find->bValid=FALSE;
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo, 22222222222\r\n")));
continue;
}
}else{ //short name.
if( pEntry_Find->bValid ){
if( ShortNameCheckSum( pDirEntry->cShortName ) !=pEntry_Find->cChecksum ){
pEntry_Find->bValid=FALSE;
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo, 333333333\r\n")));
}
}
if( pEntry_Find->bLongName && pEntry_Find->bValid ){
wcscpy(pFindData->csName, pEntry_Find->csName);
//mywcstombs((char*)pFindData->csName, (WCHAR*)pEntry_Find->csName, MAX_PATH );
}else{
///******************************************************
CopyShortName( pFindData->csName, pDirEntry );
}
pFindData->dwFileAttributes=pDirEntry->cAttr;
//ParseFileTime( &pFindData->ftCreationTime, &pDirEntry->mDateCreated, &pDirEntry->mTimeCreated );
//ParseFileTime( &pFindData->ftLastAccessTime,&pDirEntry->mLastAccessDate,&pDirEntry->mTimeLastWrite);
//ParseFileTime( &pFindData->ftLastWriteTime, &pDirEntry->mDateLastWrite ,&pDirEntry->mTimeLastWrite);
pFindData->nFileSizeHigh=0;
pFindData->nFileSizeLow=pDirEntry->dwFileSize;
pFindData->dwFirstCluster= FAT_MAKDWORD(pDirEntry->wFirstClusterHigh,pDirEntry->wFirstClusterLow );
//RETAILMSG( DEBUG_FAT,(TEXT("FAT GetFileInfo, NAME %s\r\n"),pFindData->csName));
return i+1;
}
}
return i;
}
int stricmp( TCHAR *src, TCHAR *dst )
{
while( *src ){
if( !*dst )
return -1;
if( *src ==*dst ){
}else if( *src + 0x20 ==*dst) {
}else if ( *src ==*dst+ 0x20) {
}else
return -1;
src++;
dst++;
}
if(*dst )
return -1;
return 0;
}
PFILE_DESC FindFile( PVOLUME_FAT pVolume , TCHAR * csName )
{
DWORD dwClusterSize=pVolume->fat_info.dwBytesPerSec*pVolume->fat_info.dwSecPerCluster ;
PUCHAR pBuf=(PUCHAR)g_BufCluster;
DWORD dwCurrCluster;
PDIR_ENTRY pDirEntry;
DWORD dwPassed;
DIR_ENTRY_FIND find_des;
PFILE_DESC pRet=NULL;
if( !pBuf )
return NULL;
if( dwClusterSize > sizeof(g_BufCluster) )
return NULL;
//We only find file in root directory.
dwCurrCluster= pVolume->fat_info.dwRootCluster;
g_FileDesc.pVolume=pVolume;
while(1){
if( !ReadCluster( pVolume, dwCurrCluster, pBuf, dwClusterSize ) )
break;
pDirEntry=(PDIR_ENTRY)pBuf;
while(1){
dwPassed=GetFileInfo( pDirEntry, (DWORD)pBuf+dwClusterSize, &g_FileDesc , &find_des );
if( dwPassed ==-1){
goto find_end;
}
if( dwPassed ==0 )
break; //go to next cluster.
RETAILMSG( 1,(L"partition %d, found \'%s\'\r\n",
g_FileDesc.pVolume->pPartInfo->dwIndex,
g_FileDesc.csName ));
if( ((g_FileDesc.dwFileAttributes & FILE_ATTR_DIRECTORY) ==0)
&&((g_FileDesc.dwFileAttributes & FILE_ATTR_VOLUME_ID) ==0) ) {
if( stricmp( g_FileDesc.csName, csName ) ==0 ){ //the file is found.
RETAILMSG( 1,(L"File \'%s\' is found\r\n",csName));
g_FileDesc.dwFirstCluster += g_FileDesc.pVolume->dwRootDirClusterNum;
g_FileDesc.bValid=TRUE;
pRet=&g_FileDesc;
goto find_end;
}
}
pDirEntry+=dwPassed;
}
dwCurrCluster=GetNextCluster( pVolume, dwCurrCluster );
if( dwCurrCluster ==-1 )
break;
}
find_end:
return pRet;
}
BOOL OpenFile( TCHAR *csName )
{
DWORD i;
PFILE_DESC pFileGotton=NULL;
RETAILMSG( 1,(L"Try to find \'%s\'\r\n", csName ));
for( i=0; i< g_dwVolume; i ++ ){
if(pFileGotton=FindFile( &g_FatInfo[i], csName ) )
break;
}
RETAILMSG( DEBUG_TEST,(L"\'%s\' is found\r\n", csName ));
RETAILMSG( DEBUG_TEST,(L"It's size is %d\r\n", pFileGotton->nFileSizeLow ));
return (BOOL)pFileGotton;
}
DWORD lReadFile(PUCHAR pBuf, DWORD dwLength)
{
ULONG ulClustersToRead = 0;
DWORD dwSector;
DWORD dwReadThisTime=0;
DWORD dwHasRead=0;
DWORD dwBufStart=(DWORD) pBuf;
static PUCHAR pClusterCache=NULL;
static DWORD dwCachedCluster=-1;
RETAILMSG( DEBUG_TEST,(L"Read entered sec per clu %d\r\n"
,g_FileDesc.pVolume->fat_info.dwSecPerCluster
,g_FileDesc.pVolume->fat_info.dwBytesPerSec));
if(!g_FileDesc.bValid ){ //the file is not opened.
RETAILMSG( DEBUG_ERROR,(L"ReadFile, file not open\r\n"));
return FALSE;
}
if( !pClusterCache ){
g_FileDesc.dwClusterSize=g_FileDesc.pVolume->fat_info.dwSecPerCluster *
g_FileDesc.pVolume->fat_info.dwBytesPerSec;
pClusterCache=(PUCHAR)g_BufCluster;
g_FileDesc.dwCurrCluster=g_FileDesc.dwFirstCluster;
g_FileDesc.dwPosInCluster=0;
g_FileDesc.nFilePointer=0;
}
dwLength=min( dwLength, g_FileDesc.nFileSizeLow -g_FileDesc.nFilePointer );
for(;dwHasRead<dwLength;) {
dwReadThisTime=dwLength -dwHasRead;
if( g_FileDesc.dwPosInCluster || dwReadThisTime < g_FileDesc.dwClusterSize ) {
if( dwCachedCluster != g_FileDesc.dwCurrCluster ){
START_SETOR_OF_CLUSTER(dwSector,g_FileDesc.pVolume, g_FileDesc.dwCurrCluster );
if(!PartitionReadDisk( g_FileDesc.pVolume->pPartInfo, dwSector,
g_FileDesc.pVolume->fat_info.dwSecPerCluster , pClusterCache) ){
RETAILMSG( DEBUG_ERROR,(L"ReadFile, partitionread failed\r\n"));
goto read_end;
}
dwCachedCluster=g_FileDesc.dwCurrCluster;
}
dwReadThisTime= min(dwLength -dwHasRead, g_FileDesc.dwClusterSize-g_FileDesc.dwPosInCluster);
memcpy(pBuf, pClusterCache+g_FileDesc.dwPosInCluster, dwReadThisTime );
g_FileDesc.dwPosInCluster+=dwReadThisTime;
if( g_FileDesc.dwPosInCluster >= g_FileDesc.dwClusterSize ) {
g_FileDesc.dwPosInCluster=0;
g_FileDesc.dwCurrCluster =GetNextCluster( g_FileDesc.pVolume,g_FileDesc.dwCurrCluster );
if( g_FileDesc.dwCurrCluster ==-1 ){
RETAILMSG( DEBUG_ERROR,(L"ReadFile, GetNextCluster failed\r\n"));
goto read_end;
}
}
}else{
dwReadThisTime= g_FileDesc.dwClusterSize;
START_SETOR_OF_CLUSTER(dwSector,g_FileDesc.pVolume, g_FileDesc.dwCurrCluster);
if(!PartitionReadDisk( g_FileDesc.pVolume->pPartInfo,
dwSector,
g_FileDesc.pVolume->fat_info.dwSecPerCluster,
pClusterCache) ){
RETAILMSG( DEBUG_ERROR,(L"ReadFile, partitionread failed 222\r\n"));
goto read_end;
}
memcpy( pBuf, pClusterCache, g_FileDesc.dwClusterSize );
g_FileDesc.dwCurrCluster =GetNextCluster( g_FileDesc.pVolume,g_FileDesc.dwCurrCluster );
if( g_FileDesc.dwCurrCluster ==-1 ){
RETAILMSG( DEBUG_ERROR,(L"ReadFile, GetNextCluster failed 222\r\n"));
goto read_end;
}
}
dwHasRead+=dwReadThisTime;
//dwLength -= dwReadThisTime;
pBuf+=dwReadThisTime;
g_FileDesc.nFilePointer+=dwReadThisTime;
if( g_FileDesc.nFilePointer >g_FileDesc.nFileSizeLow ){
RETAILMSG( DEBUG_ERROR,(L"ReadFile, .nFilePointer >nFileSize\r\n"));
return FALSE;
}
}
RETAILMSG( DEBUG_TEST,(L"read %d get %d pointer %d\r\n",dwLength, dwHasRead, g_FileDesc.nFilePointer));
return dwHasRead;
read_end:
pClusterCache=NULL;
dwCachedCluster=-1;
return dwHasRead;
}
#pragma pack(pop)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -