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

📄 fatmaster.cpp

📁 可以为FAT32下的文件加入tag
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <string.h>
#include <BaseTsd.h>
#include "FatMaster.h"

using namespace::std;
/* suppose using E: as default */

BOOL FatMaster::WriteTags(const char* pfileName, char* pTags, PUINT32 tagsNum)
{
	char* pFilePath = const_cast<char*> (pfileName);
	FILEENTINFO fileEntInfo;
	DWORD err;
	BOOL bRet = false;
	do {
		if( !(bRet = GetDiskName(&pFilePath, (char*)&diskName)) ) {
			break;
		}
		hDisk = OpenDisk((char*)&diskName);
		if( hDisk == INVALID_HANDLE_VALUE ){
			break;
		}
		if( ! GetBPBofDisk(hDisk) ){
			break;
		}
		if( !(bRet = GetFileEntry(hDisk, pFilePath, &fileEntInfo)) ) {
			break;
		}
		if( !(bRet = WriteTagsIn(&fileEntInfo, pTags, tagsNum)) ) {
			break;
		}
	}while(0);

	if(hDisk)
		CloseDisk(hDisk);
	return bRet;
}

BOOL FatMaster::ReadTags(const char* pfileName, char** ppTags, PUINT32 tagsNum)
{
	char* pFilePath = const_cast<char*> (pfileName);
	FILEENTINFO fileEntInfo;
	DWORD err;
	BOOL bRet = false;
	do {
		if( !(bRet = GetDiskName(&pFilePath, (char*)&diskName)) ) {
			break;
		}
		hDisk = OpenDisk((char*)&diskName);
		if( hDisk == INVALID_HANDLE_VALUE ){
			break;
		}
		if( ! GetBPBofDisk(hDisk) ){
			break;
		}
		if( !(bRet = GetFileEntry(hDisk, pFilePath, &fileEntInfo)) ) {
			break;
		}
		if( !(bRet = ReadTagsOut(&fileEntInfo, ppTags, tagsNum)) ) {
			break;
		}
	}while(0);

	if(hDisk)
		CloseDisk(hDisk);
	return bRet;
}

BOOL FatMaster::WriteFATFile(const char* pfileName, char* pBuffer, PUINT32 size)
{
	char* pFilePath = const_cast<char*> (pfileName);
	DWORD err;
	BOOL bRet = false;
	do {
		if( !(bRet = GetDiskName(&pFilePath, (char*)&diskName)) ) {
			break;
		}
		hDisk = OpenDisk((char*)&diskName);
		if( hDisk == INVALID_HANDLE_VALUE ){
			break;
		}
		if( ! GetBPBofDisk(hDisk) ){
			break;
		}
		FILEENTINFO fileEntInfo;
		if( !(bRet = GetFileEntry(hDisk, pFilePath, &fileEntInfo)) ) {
			break;
		}
		UINT32 fstSecofFile = (fileEntInfo.firCluNum - 2)*secPerClu + fstSecofRootDir;
		LARGE_INTEGER startPosOffset;
		startPosOffset.QuadPart = ((LONGLONG)fstSecofFile)*512;
		startPosOffset.LowPart = SetFilePointer(hDisk, startPosOffset.LowPart, &(startPosOffset.HighPart), FILE_BEGIN);
		if( (startPosOffset.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR) ){
			break;
		}

		DWORD writeSize;
		DWORD wantSize = *size;
		LPCVOID p = (LPVOID)pBuffer;
		bRet = WriteFile(hDisk, p, wantSize, &writeSize, NULL);
		if( !bRet ) {
			err = GetLastError();
		}
	} while(0);

	if(hDisk)
		CloseDisk(hDisk);
	return bRet;
}

BOOL FatMaster::ReadFATFile(const char* pfileName, char** ppBuffer, PUINT32 size)
{
	char* pFilePath = const_cast<char*> (pfileName);
	BOOL bRet;
	do {
		if( !(bRet = GetDiskName(&pFilePath, (char*)&diskName)) ) {
			break;
		}
		hDisk = OpenDisk((char*)&diskName);
		if( hDisk == INVALID_HANDLE_VALUE ){
			break;
		}
		if( ! GetBPBofDisk(hDisk) ){
			break;
		}
		FILEENTINFO fileEntInfo;
		if( !(bRet = GetFileEntry(hDisk, pFilePath, &fileEntInfo)) ) {
			break;
		}
		UINT32 fstSecofFile = (fileEntInfo.firCluNum - 2)*secPerClu + fstSecofRootDir;
		LARGE_INTEGER startPosOffset;
		startPosOffset.QuadPart = ((LONGLONG)fstSecofFile)*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;
		wantSize = ( fileEntInfo.length + SEC_SIZE - 1 ) / SEC_SIZE;
		wantSize = wantSize*SEC_SIZE;
		*ppBuffer = new char[wantSize];
		bRet = ReadFile(hDisk, *ppBuffer, wantSize, &readSize, NULL);
		*size = readSize;
	} while(0);

	if(hDisk)
		CloseDisk(hDisk);
	return bRet;
}

BOOL FatMaster::GetBPBofDisk(HANDLE hDev)
{
	BYTE buffer[512];
	DWORD readSize;
	BOOL Ret = ReadFile(hDev, buffer, 512, &readSize, 0);
	if( (!Ret) || (readSize != 512) ) {
		cout<<"ReadFile error with errno:"<<GetLastError()<<endl;
		return false;
	}

	secPerClu = (BYTE) buffer[0x0d];
	rsvSecNum = *((WORD*) &buffer[0x0e]);
	numofFat = (BYTE) buffer[0x10];
	maxSecNum = *((UINT32*) &buffer[0x20]);
	if( rootEntNum = *((WORD*) &buffer[0x11]) ){
		secPerFat = *((WORD*) &buffer[0x16]);
		bFat32 = false;
		//not support FAT16 now
		return false;
	} else {
		secPerFat = *((UINT32*) &buffer[0x24]);
		bFat32 = true;
	}

	fstSecofRootDir = secPerFat*numofFat + rsvSecNum;
	fstSecofData = fstSecofRootDir + (rootEntNum*DIR_ENT_SIZE + SEC_SIZE -1)/SEC_SIZE;
	fstSecofFat = rsvSecNum;
	maxCluNum = ( maxSecNum - fstSecofData )/secPerClu + FIR_CLU;

	return true;
}

BOOL FatMaster::GetDiskName(char** ppFilePath, char* pdiskName)
{
	const char *p = strchr((*ppFilePath), ':');
	if(p == NULL) {
		return false;
	}
	int size = p - (*ppFilePath) + 1;
	if( size < 0 || size > 7 ) {
		return false;
	}
	strncpy(pdiskName, (*ppFilePath), size);
	pdiskName[size] = '\0';	
	*ppFilePath = (char*) p + 1;
	return true;
}

BOOL FatMaster::GetFileEntry(HANDLE hDisk, char *pFilePath, PFILEENTINFO pFileEntInfo)
{
	BOOL bRet = false;
	BOOL bFind = false;
	INT32 iRet;
	char *pPathName = pFilePath;
	char dirName[128];
	
	UINT32 searchStartSec = fstSecofRootDir;
	const char* p = strchr(pPathName, '\\');
	pPathName = (char*)p + 1;
	//Indicate continue to find loop or not
	BOOL bLoop = true;

	/* Search the first match Entry process differ from follows.
	 * It will make extension to FAT16 easily
	 */
	if( strlen(pPathName) != 0 ) {
		iRet = GetTopDirName(&pPathName, (char*)dirName);
		switch(iRet) {
			case 1:
				if( !(bRet = SearchRootFileEnt(hDisk, searchStartSec, (char*)dirName, pFileEntInfo)) ){
					bLoop = false;
				}else{
					searchStartSec = (pFileEntInfo->firCluNum - 2)*secPerClu + fstSecofRootDir;
				}
				break;
			case 0:
				bLoop = false;
				bRet = SearchRootFileEnt(hDisk, searchStartSec, (char*) pPathName, pFileEntInfo);
				bFind = bRet;
				break;
			case -1:
			default:
				bLoop = false;
				break;
		}
	}	
	while( strlen(pPathName) > 0 && bLoop) {
		iRet = GetTopDirName(&pPathName, (char*)dirName);
		switch(iRet) {
			case 1:
				if( !(bRet = SearchFileEntByName(hDisk, searchStartSec, (char*) dirName, pFileEntInfo)) ) {
					bLoop = false;
				}else{
					searchStartSec = (pFileEntInfo->firCluNum - 2)*secPerClu + fstSecofRootDir;
				}
				break;
			case 0:
				bLoop = false;
				bRet = SearchFileEntByName(hDisk, searchStartSec, (char*) pPathName, pFileEntInfo);
				bFind = bRet;
				break;
			case -1:
			default:
				bLoop = false;
				break;
		}
	}
	return bFind;
}

/* return value:
* 1 success
* 0 meet the file not directory
* -1 error
*
*/
INT32 FatMaster::GetTopDirName(char** ppPath, char* pDirName)
{
	char *pRight = (char*)strchr( *ppPath, '\\');
	if(pRight == NULL) {
		return 0;
	}
	int size = pRight - (*ppPath);
	if(size < 0 || size > 127) {
		return -1;
	}
	strncpy(pDirName, *ppPath, size);
	pDirName[size] = '\0';
	*ppPath = pRight + 1;
	return 1;
}

BOOL FatMaster::SearchRootFileEnt(HANDLE hDisk, UINT32 startSecNum, char* pName, PFILEENTINFO pFileEntInfo)
{
	if(bFat32){
		return SearchFileEntByName(hDisk, startSecNum, pName, pFileEntInfo);
	}
	return false;
}

⌨️ 快捷键说明

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