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

📄 fatmaster.cpp

📁 可以为FAT32下的文件加入tag
💻 CPP
📖 第 1 页 / 共 2 页
字号:
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 + -