📄 fatmaster.cpp
字号:
BOOL FatMaster::SearchFileEntByName(HANDLE hDisk, UINT32 startSecNum, char* pName, PFILEENTINFO pFileEntInfo)
{
int rootDirEntSeq = 0;
BOOL bRet = false;
/* parse file name */
BOOL bLongName = false;
UINT32 nameSize = strlen(pName);
FILE_NAME name;
char* p = (char*)strrchr(pName, '.');
if( p != NULL ){
name.preSize = p - pName;
strncpy((char*)name.preName, pName, name.preSize);
name.extSize = nameSize - name.preSize - 1;
strncpy((char*)name.extName, p+1, name.extSize);
}else{
name.preSize = nameSize;
strncpy((char*)name.preName, pName, name.preSize);
name.extSize = 0;
}
if( strchr((char*)name.preName, '.') ){
//don't support such file name
return false;
}
if( (name.preSize > 8) || (name.extSize > 3) ) {
bLongName = true;
}
PFAT32_DIR_ENT pdirEnt;
bool notFound = true;
UINT32 cluSize = secPerClu*SEC_SIZE;
DWORD loopNum, wantsize, readsize;
if( secPerClu > 8 ){
//If secPerClu more than 8 , it is certain multiple of 8 (16, 32...)
loopNum = secPerClu/8;
wantsize = BUF_SIZE;
} else {
loopNum = 1;
wantsize = cluSize;
}
UINT32 curCluSeq = (startSecNum - fstSecofData)/secPerClu + 2;
UINT32 curSecSeq = startSecNum;
LARGE_INTEGER startPosOffset;
PBYTE pCur, pLst;
memset(mBuf, 0, sizeof(mBuf));
while( notFound ) {
startPosOffset.QuadPart = ((LONGLONG)curSecSeq)*SEC_SIZE;
startPosOffset.LowPart = SetFilePointer(hDisk, startPosOffset.LowPart, &(startPosOffset.HighPart), FILE_BEGIN);
if( (startPosOffset.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR) ){
return false;
}
for(UINT32 i=0; i<loopNum && notFound; i++) {
pCur = mBuf+(i&0x1)*BUF_SIZE;
pLst = mBuf+((i+1)&0x1)*BUF_SIZE;
bRet = ReadFile(hDisk, pCur, wantsize, &readsize, NULL);
if( !bRet || (readsize != wantsize) ) {
return false;
}
int entNum = (readsize + DIR_ENT_SIZE -1)/DIR_ENT_SIZE;
for(int j=0; j<entNum && notFound; j++) {
UINT32 pos = DIR_ENT_SIZE*j;
pdirEnt = (PFAT32_DIR_ENT) (pCur+pos);
if(pdirEnt->name[0] == 0xE5){
continue;
} else if( pdirEnt->name[0] == 0x00 ){
return false;
} else if ( !bLongName && MatchSNameWithSEnt(&name, pdirEnt) ) {
notFound = false;
} else if ( MatchLNameWithSEnt(&name, pdirEnt) && MatchLNameWithLEnt(pName, pos, pCur, pLst)){
notFound = false;
}
}
}
if( notFound && (bRet = FindNextCluSeq(&curCluSeq, 1)) ){
curSecSeq = (curCluSeq - 2)*secPerClu + fstSecofData;
} else {
bRet = false;
break;
}
}
if( !notFound ) {
pFileEntInfo->firCluNum = (((UINT32)(pdirEnt->fstCluHi)) << 16) & 0xFFFF0000;
pFileEntInfo->firCluNum = pFileEntInfo->firCluNum | pdirEnt->fstCluLo;
pFileEntInfo->length = pdirEnt->length;
bRet = true;
}
return bRet;
}
BOOL FatMaster::FindNextCluSeq(PUINT32 pCluNum, int num)
{
UINT32 nxtClu = *pCluNum;
UINT32 curClu = *pCluNum;
BOOL bRet = false;
UINT32 wantsize = SEC_SIZE;
UINT32 readsize = 0;
UINT32 offset = 0;
UINT32 fatSecSeq = 0;
UINT32 lstSecSeq = 0;
LARGE_INTEGER startPosOffset;
memset(mBuf, 0, wantsize);
for(int i=0; i<num; i++){
curClu = nxtClu;
fatSecSeq = fstSecofFat + (curClu*4)/SEC_SIZE;
if( lstSecSeq != fatSecSeq ) {
lstSecSeq = fatSecSeq;
startPosOffset.QuadPart = ((LONGLONG)fatSecSeq)*SEC_SIZE;
startPosOffset.LowPart = SetFilePointer(hDisk, startPosOffset.LowPart, &(startPosOffset.HighPart), FILE_BEGIN);
if( (startPosOffset.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR) ){
return false;
}
bRet = ReadFile(hDisk, (char*)mBuf, wantsize, (LPDWORD)&readsize, NULL);
if( !bRet || (wantsize != readsize) ) {
return false;
}
}
offset = (curClu*4)%SEC_SIZE;
nxtClu = *((PUINT32)(mBuf+offset));
if( nxtClu > maxCluNum || nxtClu > 0xfffffff8 )
return false;
}
*pCluNum = nxtClu;
return true;
}
BOOL FatMaster::MatchLNameWithSEnt(FILE_NAME* pName, PFAT32_DIR_ENT pdirEnt)
{
char* name = new char[pName->preSize];
char* ext = new char[pName->extSize];
strncpy(name, pName->preName, pName->preSize);
strncpy(ext, pName->extName, pName->extSize);
name = _strupr(name);
ext = _strupr(ext);
UINT32 namelen = pName->preSize;
UINT32 extlen = pName->extSize;
if( namelen > 6 )
namelen = 6;
if( extlen > 3 )
extlen = 3;
if( strncmp(name, (char*)pdirEnt->name, namelen) )
return false;
if( (pName->extSize != 0) && strncmp(ext, (char*)pdirEnt->ext, extlen) )
return false;
if( (extlen == 0) && (pdirEnt->ext[0] != 0x20) )
return false;
return true;
}
BOOL FatMaster::MatchLNameWithLEnt(char* pName, UINT32 pos, PBYTE pCur, PBYTE pLst)
{
PLONG_NAME_ENT pDir;
UINT32 len = strlen(pName);
char* p = pName;
UINT32 tmp_pos = pos;
UINT32 nloop = len/CHAR_PER_LDIR;
UINT32 nres = len%CHAR_PER_LDIR;
for(int i=0; i<nloop; i++){
if( tmp_pos >= 32 ){
tmp_pos -= 32;
pDir = (PLONG_NAME_ENT)(pCur+tmp_pos);
} else {
if(tmp_pos == 0){
tmp_pos = BUF_SIZE - 32;
} else {
tmp_pos -= 32;
}
pDir = (PLONG_NAME_ENT)(pLst+tmp_pos);
}
if( ComCharAndWchar(p, pDir->name1, 5) && ComCharAndWchar(p+5, pDir->name2, 6) && ComCharAndWchar(p+11, pDir->name3, 2) )
return false;
p = p + 13;
}
if(nres > 0){
if( tmp_pos >= 32 ){
tmp_pos -= 32;
pDir = (PLONG_NAME_ENT)(pCur+tmp_pos);
} else {
if(tmp_pos == 0){
tmp_pos = BUF_SIZE - 32;
} else {
tmp_pos -= 32;
}
pDir = (PLONG_NAME_ENT)(pLst+tmp_pos);
}
if( nres<5 && ComCharAndWchar(p, pDir->name1, nres) )
return false;
else if( nres<11 && ComCharAndWchar(p, pDir->name1, 5) && ComCharAndWchar(p+5, pDir->name2, nres-5) )
return false;
else if( ComCharAndWchar(p, pDir->name1, 5) && ComCharAndWchar(p+5, pDir->name2, 6) && ComCharAndWchar(p+11, pDir->name3, nres-11) )
return false;
}
return true;
}
BOOL FatMaster::MatchSNameWithSEnt(FILE_NAME* pName, PFAT32_DIR_ENT pdirEnt)
{
char* name = new char[pName->preSize];
char* ext = new char[pName->extSize];
strncpy(name, pName->preName, pName->preSize);
strncpy(ext, pName->extName, pName->extSize);
name = _strupr(name);
ext = _strupr(ext);
if( strncmp(name, (char*)pdirEnt->name, pName->preSize) )
return false;
if( (pName->extSize != 0) && strncmp(ext, (char*)pdirEnt->ext, pName->extSize) )
return false;
if( (pName->extSize == 0) && (pdirEnt->ext[0] != 0x20) )
return false;
return true;
}
BOOL FatMaster::WriteTagsIn( PFILEENTINFO pfileEntInfo, char* pTags, PUINT32 tagsNum)
{
BOOL bRet;
UINT32 secSeq;
do{
if( !LocateFileLastSec( pfileEntInfo, &secSeq ) )
break;
LARGE_INTEGER startPosOffset;
startPosOffset.QuadPart = ((LONGLONG)secSeq)*512;
startPosOffset.LowPart = SetFilePointer(hDisk, startPosOffset.LowPart, &(startPosOffset.HighPart), FILE_BEGIN);
if( (startPosOffset.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR) ){
break;
}
DWORD wantSize, writeSize;
wantSize = ((*tagsNum + SEC_SIZE - 1)/SEC_SIZE) * SEC_SIZE;
//wantSize
bRet = WriteFile(hDisk, pTags, wantSize, &writeSize, NULL);
*tagsNum = writeSize;
}while(0);
return bRet;
}
BOOL FatMaster::ReadTagsOut( PFILEENTINFO pfileEntInfo, char** ppTags, PUINT32 tagsNum)
{
BOOL bRet;
UINT32 secSeq;
do{
if( !LocateFileLastSec( pfileEntInfo, &secSeq ) )
break;
LARGE_INTEGER startPosOffset;
startPosOffset.QuadPart = ((LONGLONG)secSeq)*512;
startPosOffset.LowPart = SetFilePointer(hDisk, startPosOffset.LowPart, &(startPosOffset.HighPart), FILE_BEGIN);
if( (startPosOffset.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR) ){
break;
}
DWORD wantSize, readSize;
BYTE buffer[SEC_SIZE];
wantSize = SEC_SIZE;
bRet = ReadFile(hDisk, &buffer, wantSize, &readSize, NULL);
(*ppTags) = new char[readSize];
memcpy(*ppTags, buffer, readSize);
*tagsNum = readSize;
}while(0);
return bRet;
}
BOOL FatMaster::LocateFileLastSec( PFILEENTINFO pfileEntInfo, PUINT32 secNum)
{
BOOL bRet = true;
if ( pfileEntInfo->length <= secPerClu*SEC_SIZE )
*secNum = (pfileEntInfo->firCluNum - 1)*secPerClu + fstSecofData - 1;
else
bRet = false;
return bRet;
}
BOOL FatMaster::ComCharAndWchar(char* pa, PWORD pb, UINT32 n)
{
//ezhnwag
int i;
for(i=0; i<n; i++){
WORD av = *(pa+i);
WORD bv = *(pb+i);
if( av != bv )
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -