📄 fatmaster.cpp
字号:
#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 + -