Files
2026-02-21 17:11:31 +09:00

3181 lines
111 KiB
C++

/*
bmff : Blackbox Media Works Format Free
jykang 20190923
*/
#if (SUPPORT_FORMAT_FREE)
#include "bmff.h"
//#include <QDebug>
#ifdef WIN32
//#define BLKGETSIZE 4096
#define BLKGETSIZE 4096 //_IO(0x12,96) // return device size /512 (long *arg) */
#define BLKFLSBUF 4096 //_IO(0x12,97) // flush buffer cache */
#define EVENT_FILE_SEC 60
typedef __int64 ssize_t;
typedef __int64 loff_t;
typedef __int64 off64_t; // off64_t
static loff_t toInteger(LARGE_INTEGER const & integer)
{
#ifdef INT64_MAX // Does the compiler natively support 64-bit integers?
return integer.QuadPart;
#else
return (static_cast<long long>(integer.HighPart) << 32) | integer.LowPart;
#endif
}
// signed long long to LARGE_INTEGER object:
static LARGE_INTEGER toLargeInteger(loff_t value)
{
LARGE_INTEGER result;
#ifdef INT64_MAX // Does the compiler natively support 64-bit integers?
result.QuadPart = value;
#else
result.HighPart = (value >> 32) & 0xFFFFFFFF;// & 0xFFFFFFFF00000000);
result.LowPart = value & 0xFFFFFFFF;
#endif
return result;
}
int GetPhysicalDrive(WCHAR DL)
{
int ret = -1;
WCHAR sBuf[1000];
WCHAR sBuffer1[255] = {0,};
WCHAR sBuffer2[50] = {0,};
DWORD nSize, nCpt;
nSize = ::GetLogicalDriveStrings(1000, sBuf);
nCpt = 0;
while (nCpt < nSize)
{
if(sBuf[nCpt] != DL) {
nCpt += lstrlen(&sBuf[nCpt]) + 1;
continue;
}
//wsprintf(sBuffer1, L"\\\\.\\%c:", DL);
//OutputDebugString(sBuffer1);
wsprintf(sBuffer1, L"\\\\.\\%s", &sBuf[nCpt]);
sBuffer1[6] = 0;
// strcpy(sBuffer1, &num[6]);
HANDLE hVol = NULL;
hVol = ::CreateFile(sBuffer1,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
int maxDisks;
BOOL b;
DWORD cbBytes;
PVOLUME_DISK_EXTENTS PVolDiskExtent;
PVolDiskExtent = (PVOLUME_DISK_EXTENTS)::LocalAlloc(LMEM_FIXED, sizeof(VOLUME_DISK_EXTENTS));
STORAGE_DEVICE_NUMBER sdn;
DWORD dwBytesReturned = 0;
b = ::DeviceIoControl(hVol, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
int nType = sdn.DeviceType;
b = ::DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, PVolDiskExtent, sizeof(VOLUME_DISK_EXTENTS), &cbBytes, NULL);
int nDiskNumber = 0;
if (!b)
{
int n = ::GetLastError();
if (n == ERROR_MORE_DATA)
{
maxDisks = PVolDiskExtent->NumberOfDiskExtents;
::LocalFree(PVolDiskExtent);
PVolDiskExtent = (PVOLUME_DISK_EXTENTS)LocalAlloc(LMEM_FIXED, sizeof(VOLUME_DISK_EXTENTS) + (sizeof(DISK_EXTENT) * maxDisks));
b = DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, PVolDiskExtent, sizeof(VOLUME_DISK_EXTENTS) + (sizeof(DISK_EXTENT) * maxDisks),
&cbBytes,
NULL);
nDiskNumber = PVolDiskExtent->Extents[0].DiskNumber;
}
else
nDiskNumber = -1;
}
else
{
nDiskNumber = PVolDiskExtent->Extents[0].DiskNumber;
}
// Disk : C:\ - Disk Number : 0 - Type : 7
// Disk : F:\ - Disk Number : 1 - Type : 7
// WCHAR wsText[255] = L"";
// wsprintf(wsText, L"Disk : %s - Disk Number : %d - Type : %d\n", &sBuf[nCpt], nDiskNumber, nType);
// OutputDebugString(wsText);
::CloseHandle(hVol);
if(DL == sBuf[nCpt]) {
return nDiskNumber;
}
nCpt += lstrlen(&sBuf[nCpt]) + 1;
}
return -1;
}
//int open64(const char *pathname, int oflag,...)
//{
// return 0;
//}
//int close(int fd)
//{
// return 0;
//}
//int fsync(int fd)
//{
// return 0;
//}
void usleep(int m) {}
int ioctl(HANDLE fd, unsigned long request,unsigned long* ret) {
// SECTOR SIZE 는 512로 되어 있으니 확인할 필요 없음
/*
Q_UNUSED(request)
DWORD outsize;
STORAGE_PROPERTY_QUERY storageQuery;
::ZeroMemory(&storageQuery, sizeof(STORAGE_PROPERTY_QUERY));
storageQuery.PropertyId = StorageAccessAlignmentProperty;
storageQuery.QueryType = PropertyStandardQuery;
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment = {0};
::ZeroMemory(&diskAlignment, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));
if (!::DeviceIoControl(fd,
IOCTL_STORAGE_QUERY_PROPERTY,
&storageQuery,
sizeof(STORAGE_PROPERTY_QUERY),
&diskAlignment,
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR),
&outsize,
NULL)
)
{
return -1;
}
// 512, 512, SIZE: 28
// 실제 SECTOR 크기만 확인가능
DWORD sectorSize =diskAlignment.BytesPerPhysicalSector; // 512
Return the device size, expressed in sectors
*/
DISK_GEOMETRY stDiskGeometry;
::ZeroMemory(&stDiskGeometry, sizeof(DISK_GEOMETRY));
DWORD dwjunk = 0;
if(!::DeviceIoControl(fd,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0, // no input buffer
&stDiskGeometry,
sizeof(DISK_GEOMETRY),
&dwjunk,
(LPOVERLAPPED) NULL))
{
return -1;
}
// Cylinders: 482 SectorsPerTrack: 63 TracksPerCylinder: 255 ioctl
//qInfo() << "Cylinders:" << toInteger(stDiskGeometry.Cylinders) << "SectorsPerTrack:" << stDiskGeometry.SectorsPerTrack << "TracksPerCylinder:" << stDiskGeometry.TracksPerCylinder << __FUNCTION__;
int64_t sz = toInteger(stDiskGeometry.Cylinders) * stDiskGeometry.SectorsPerTrack * stDiskGeometry.TracksPerCylinder;
// *ret = sz;
int64_t numCluster = sz / SECTORS_PER_CLUSTER;
*ret = numCluster * SECTORS_PER_CLUSTER;
// *ret /= 8;
// *ret = (int64_t)(*ret / SECTOR_SIZE) * SECTOR_SIZE; // 512???
if((*ret < MIN_SECTORS) || (*ret > MAX_SECTORS)) {
return -1;
}
return 0;
}
ssize_t read(HANDLE fd, void* buffer, size_t count){
DWORD dwRead;
if(!::ReadFile(fd,
buffer,
count,
&dwRead,
NULL)) {
return -1;
}
return dwRead;
}
ssize_t write(HANDLE fd, void* buffer, size_t count){ // , OVERLAPPED* pOV
//return count;
DWORD dwWrite;
LPVOID nb = ::VirtualAlloc(NULL,count,MEM_COMMIT,PAGE_READWRITE);
::CopyMemory(nb,buffer,count);
// (LPOVERLAPPED)&m_ov[page])
// OVERLAPPED ol = {0,};
// LARGE_INTEGER move = {0,};
// LARGE_INTEGER np;
// ::SetFilePointerEx(fd,move,&np,FILE_CURRENT);
// pOV->Offset = lp.LowPart;
// pOV->OffsetHigh = lp.HighPart;
// ol.Offset = np.LowPart;
// ol.OffsetHigh = np.HighPart;
// printf("FP:%X:%X\n",ol.Offset, ol.OffsetHigh);
if(!::WriteFile(fd,nb,count,&dwWrite,NULL)) {
//if(!::WriteFileEx(fd,buffer,count,pOV,NULL)) {
DWORD dwError = ::GetLastError();
wchar_t buf[256] = {0,};
::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), // LANG_NEUTRAL
buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
wprintf(buf);
::VirtualFree(nb,count,0);
return -1;
}
::VirtualFree(nb,count,0);
// lp.QuadPart += dwWrite;
// ::SetFilePointerEx(fd,lp,&dummy,FILE_CURRENT);
return ((ssize_t)dwWrite);
}
off64_t lseek64(HANDLE fd, off64_t offset, int whence)
{
DWORD dwMoveMethod = FILE_BEGIN;
if(whence == SEEK_CUR) {
dwMoveMethod = FILE_CURRENT;
}
else if(whence == SEEK_END) {
dwMoveMethod = FILE_END;
}
//loff_t pos = FIRST_SECTOR * SECTOR_SIZE;
LARGE_INTEGER liSize = toLargeInteger(offset);
// liSize.LowPart = (int)(offset & 0xFFFFFFFF);
// liSize.HighPart = (int)(offset >> 32);
LARGE_INTEGER offsetL;
offsetL.LowPart = ::SetFilePointer(fd,liSize.LowPart,&liSize.HighPart,dwMoveMethod);
offsetL.HighPart = liSize.HighPart;
if(offsetL.QuadPart != liSize.QuadPart)
//if(!::SetFilePointerEx(fd,liSize,&offsetL,dwMoveMethod))
{
printf("LSEEK ERROR:%I64d",offset);
return -1;
}
return (off64_t)offsetL.QuadPart;// toInteger(offsetL);
//loff_t offset = lseek64(mFd, (loff_t)FIRST_SECTOR * SECTOR_SIZE, SEEK_SET);
//return 0;
}
#else // WIN32
#include "bmconfig.h"
#include <dirent.h>
#endif // WIN32
#include <string.h>
BmFF::BmFF()
{
setbuf(stdout, NULL);
// C99 오류
mNoPrintFlag = false;
FIRST_SECTOR = 2048;
mMstarPark = false;
mEmmc = false;
mRootDirectoryStartCluster = 2;
mRootDirectoryClusters = 1;
mLogDirectoryClusters = 1;
mNormalPercent = 60;
mEventPercent = 15;
mManualPercent = 5;
mPtTotalSectors = 0;
mSectorsPerFat = 0;
#if(MODEL_CONFIG == MH3000)
mParkingNormalPercent = 0;
#else
mParkingNormalPercent = 18;
#endif //
mParkingEventPercent = 2;
mRecoverFlag = false;
mFormatFlag = false;
mRecovered = false;
mSerialNumber = 0;
mMakeFactoryAging = false;
mFd = NULL;
}
int BmFF::Init(const char *device, int normalFrontFileSize, int normalRearFileSize,
int eventFrontFileSize, int eventRearFileSize,
int parkFrontFileSize, int parkRearFileSize)
{
mDeviceName = device;
mNormalFrontFileClusters = normalFrontFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(normalFrontFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mNormalFrontFileClusters;
mNormalRearFileClusters = normalRearFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(normalRearFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mNormalRearFileClusters;
mEventFrontFileClusters = eventFrontFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(eventFrontFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mEventFrontFileClusters;
mEventRearFileClusters = eventRearFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(eventRearFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mEventRearFileClusters;
mParkingFrontFileClusters = parkFrontFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(parkFrontFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mParkingFrontFileClusters;
mParkingRearFileClusters = parkRearFileSize / (SECTORS_PER_CLUSTER * SECTOR_SIZE);
if(parkRearFileSize % (SECTORS_PER_CLUSTER * SECTOR_SIZE) != 0)
++mParkingRearFileClusters;
mManualFrontFileClusters = mEventFrontFileClusters;
mManualRearFileClusters = mEventRearFileClusters;
mFlushStartOffset = 0;
if(!mNoPrintFlag)
printf("NF_Clusters:%d, NR_Clusters:%d, EF_Clusters:%d, ER_Clusters:%d, PF_Clusters:%d, PR_Clusters=%d\n",
mNormalFrontFileClusters, mNormalRearFileClusters, mEventFrontFileClusters, mEventRearFileClusters,
mParkingFrontFileClusters, mParkingRearFileClusters);
return 0;
}
void BmFF::SetStoragePercent(bool park)
{
if(mMstarPark)
{
#if (MODEL_CONFIG == UPK045)
if(park)
{
mNormalPercent = 55;
mParkingNormalPercent = 20;
mEventPercent = 20;
}
else
{
mNormalPercent = 65;
mParkingNormalPercent = 0;
mEventPercent = 30;
}
mManualPercent = 5;
mParkingEventPercent = 0;
#elif (MODEL_CONFIG == MH3000)
mNormalPercent = 88;
mParkingNormalPercent = 0;
mEventPercent = 12;
mManualPercent = 0;
mParkingEventPercent = 0;
#elif (MODEL_CONFIG == BV3000 || MODEL_CONFIG == BV600)
if(park)
{
mNormalPercent = 50;
mParkingNormalPercent = 20;
}
else
{
mNormalPercent = 70;
mParkingNormalPercent = 0;
}
mEventPercent = 20;
mManualPercent = 10;
mParkingEventPercent = 0;
#elif (MODEL_CONFIG == R093)
if(park)
{
mNormalPercent = 60;
mParkingNormalPercent = 15;
mEventPercent = 20;
}
else
{
mNormalPercent = 65;
mParkingNormalPercent = 0;
mEventPercent = 30;
}
mManualPercent = 5;
mParkingEventPercent = 0;
#elif (MODEL_CONFIG == FRC)
// if(park)
// {
// mNormalPercent = 50;
// mParkingNormalPercent = 20;
// }
// else
// {
// mNormalPercent = 70;
// mParkingNormalPercent = 0;
// }
// mEventPercent = 20;
// mManualPercent = 10;
// mParkingEventPercent = 0;
if(access("/tmp/bmff_frc_65_15_5_15", F_OK) == 0)
{
mNormalPercent = 65;
mEventPercent = 15;
mManualPercent = 5;
mParkingNormalPercent = 15;
mParkingEventPercent = 0;
printf("frc partition: 65, 15, 5, 15\n");
}
else if(access("/tmp/bmff_frc_20_75_5_0", F_OK) == 0)
{
mNormalPercent = 20;
mEventPercent = 75;
mManualPercent = 5;
mParkingNormalPercent = 0;
mParkingEventPercent = 0;
printf("frc partition: 20, 75, 5, 0\n");
}
else if(access("/tmp/bmff_frc_20_60_5_15", F_OK) == 0)
{
mNormalPercent = 20;
mEventPercent = 60;
mManualPercent = 5;
mParkingNormalPercent = 15;
mParkingEventPercent = 0;
printf("frc partition: 20, 60, 5, 15\n");
}
else if(access("/tmp/bmff_frc_20_20_5_55", F_OK) == 0)
{
mNormalPercent = 20;
mEventPercent = 20;
mManualPercent = 5;
mParkingNormalPercent = 55;
mParkingEventPercent = 0;
printf("frc partition: 20, 20, 5, 55\n");
}
else // 80_15_5_0
{
mNormalPercent = 80;
mEventPercent = 15;
mManualPercent = 5;
mParkingNormalPercent = 0;
mParkingEventPercent = 0;
printf("frc partition: 80, 15, 5, 0\n");
}
#else
int ret;
ret = OpenDevice();
if(ret != 0) return;
ret = GetBlocksFirst();
CloseDevice();
if(mBlocks > 100 * 1024 * 1024 * 2) // if bigger then 100GB
{
if(park)
{
mNormalPercent = 60;
mParkingNormalPercent = 30;
}
else
{
mNormalPercent = 90;
mParkingNormalPercent = 0;
}
mEventPercent = 8;
mManualPercent = 2;
mParkingEventPercent = 0;
}
else
{
if(park)
{
mNormalPercent = 55;
mParkingNormalPercent = 30;
}
else
{
mNormalPercent = 85;
mParkingNormalPercent = 0;
}
mEventPercent = 13;
mManualPercent = 2;
mParkingEventPercent = 0;
}
#endif
}
else if(park)
{
mNormalPercent = 60;
mEventPercent = 15;
mManualPercent = 5;
mParkingNormalPercent = 18;
mParkingEventPercent = 2;
}
else
{
mNormalPercent = 80;
mEventPercent = 15;
mManualPercent = 5;
mParkingNormalPercent = 0;
mParkingEventPercent = 0;
}
}
int BmFF::Init2(const char *device, int frontHeight, int rearHeight, int frontFps, int parkFps)
{
int frontFileSize,
rearFileSize;
int frontParkFileSize,
rearParkFileSize;
int frontEventFileSize,
rearEventFileSize;
#if EVENT_FILE_SEC
int event_sec = EVENT_FILE_SEC;
#else
int event_sec = 30;
#endif
#if (MODEL_CONFIG == FRC)
int rearFps = 27;
#elif (MODEL_CONFIG == MH3000)
int rearFps = 24;
#else
int rearFps = 30;
#endif
frontFileSize = GetFileSize(frontHeight, frontFps);
rearFileSize = GetFileSize(rearHeight, rearFps);
if(parkFps > 0)
{
frontParkFileSize = GetFileSize(frontHeight, parkFps);
if(mMstarPark)
{
#if (MODEL_CONFIG == UPK045 || MODEL_CONFIG == BV3000 || MODEL_CONFIG == BV600)
rearParkFileSize = rearFileSize;
#elif (MODEL_CONFIG == FRC)
rearParkFileSize = rearFileSize;
#elif (MODEL_CONFIG == MH6200E)
rearParkFileSize = rearFileSize;
#else
rearParkFileSize = GetFileSize(rearHeight, parkFps);
#endif
frontParkFileSize = (frontParkFileSize > 0) ? GET_FILE_SIZE_BY_SEC(frontParkFileSize, event_sec) : 0;
rearParkFileSize = (rearParkFileSize > 0) ? GET_FILE_SIZE_BY_SEC(rearParkFileSize, event_sec) : 0;
}
else
rearParkFileSize = rearFileSize;
}
else
{
frontParkFileSize = 0;
rearParkFileSize = 0;
}
if(mMstarPark)
{
frontEventFileSize = (frontFileSize > 0) ? GET_FILE_SIZE_BY_SEC(frontFileSize, event_sec) : 0;
rearEventFileSize = (rearFileSize > 0) ? GET_FILE_SIZE_BY_SEC(rearFileSize, event_sec) : 0;
}
else
{
frontEventFileSize = frontFileSize;
rearEventFileSize = rearFileSize;
}
mDeviceName = device;
SetStoragePercent(parkFps > 0);
UpdateInfoFirst();
if(!mNoPrintFlag) printf("================================================================\n");
if(!mNoPrintFlag) printf(" frontHeight = %d, rearHeight = %d\n", frontHeight, rearHeight);
if(!mNoPrintFlag) printf(" frontFileSize = %dMb, rearFileSize = %dMb\n", frontFileSize / MiB, rearFileSize / MiB);
if(!mNoPrintFlag) printf(" frontParkFileSize = %dMb, rearParkFileSize = %dMb\n", frontParkFileSize / MiB, rearParkFileSize / MiB);
if(!mNoPrintFlag) printf(" frontEventFileSize = %dMb, rearEventFileSize = %dMb\n", frontEventFileSize / MiB, rearEventFileSize / MiB);
if(!mNoPrintFlag) printf("================================================================\n");
return Init(device, frontFileSize, rearFileSize, frontEventFileSize, rearEventFileSize, frontParkFileSize, rearParkFileSize);
}
int BmFF::GetFileSize(int height, int fps)
{
int fileSize = -1;
switch(height)
{
case 1920:
switch(fps)
{
case 30:
fileSize = SQ1920_30_FILE_SIZE;
break;
case 29:
fileSize = SQ1920_30_FILE_SIZE;
break;
case 27:
fileSize = SQ1920_27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = SQ1920_25_FILE_SIZE;
break;
case 22:
fileSize = SQ1920_22_FILE_SIZE;
break;
case 16:
fileSize = SQ1920_16_FILE_SIZE;
break;
case 7:
fileSize = SQ1920_07_FILE_SIZE;
break;
case 6:
fileSize = SQ1920_06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 1440:
switch(fps)
{
case 30:
fileSize = WQHD30_FILE_SIZE;
break;
case 29:
fileSize = WQHD30_FILE_SIZE;
break;
case 27:
fileSize = WQHD27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = WQHD25_FILE_SIZE;
break;
case 22:
fileSize = WQHD22_FILE_SIZE;
break;
case 16:
fileSize = WQHD16_FILE_SIZE;
break;
case 7:
fileSize = WQHD07_FILE_SIZE;
break;
case 6:
fileSize = WQHD06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 1296:
switch(fps)
{
case 30:
fileSize = SHD30_FILE_SIZE;
break;
case 29:
fileSize = SHD30_FILE_SIZE;
break;
case 27:
fileSize = SHD27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = SHD25_FILE_SIZE;
break;
case 22:
fileSize = SHD22_FILE_SIZE;
break;
case 16:
fileSize = SHD16_FILE_SIZE;
break;
case 7:
fileSize = SHD07_FILE_SIZE;
break;
case 6:
fileSize = SHD06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 1600:
switch(fps)
{
case 30:
fileSize = SQ1600_30_FILE_SIZE;
break;
case 29:
fileSize = SQ1600_30_FILE_SIZE;
break;
case 27:
fileSize = SQ1600_27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = SQ1600_25_FILE_SIZE;
break;
case 22:
fileSize = SQ1600_22_FILE_SIZE;
break;
case 16:
fileSize = SQ1600_16_FILE_SIZE;
break;
case 7:
fileSize = SQ1600_07_FILE_SIZE;
break;
case 6:
fileSize = SQ1600_06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 1080:
switch(fps)
{
case 30:
fileSize = FHD30_FILE_SIZE;
break;
case 29:
fileSize = FHD30_FILE_SIZE;
break;
case 27:
fileSize = FHD27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = FHD25_FILE_SIZE;
break;
case 22:
fileSize = FHD22_FILE_SIZE;
break;
case 16:
fileSize = FHD16_FILE_SIZE;
break;
case 7:
fileSize = FHD07_FILE_SIZE;
break;
case 6:
fileSize = FHD06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 720:
switch(fps)
{
case 30:
fileSize = HD30_FILE_SIZE;
break;
case 29:
fileSize = HD30_FILE_SIZE;
break;
case 27:
fileSize = HD27_FILE_SIZE;
break;
case 25:
case 24:
fileSize = HD25_FILE_SIZE;
break;
case 22:
fileSize = HD22_FILE_SIZE;
break;
case 16:
fileSize = HD16_FILE_SIZE;
break;
case 7:
fileSize = HD07_FILE_SIZE;
break;
case 6:
fileSize = HD06_FILE_SIZE;
break;
default:
goto error;
}
break;
case 0:
fileSize = 0;
break;
default:
goto error;
}
return fileSize;
error:
printf("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");
printf(" Error GetFileSize()..height=%d, fps=%d\n", height, fps);
printf("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");
return -1;
}
int BmFF::MakeDisk(void)
{
mFormatFlag = true;
UpdateInfo();
MakeMBR();
MakeFATBS();
WriteAll();
mFormatFlag = false;
// usleep(1000 * 1000);
// WriteAll();
// usleep(1000 * 1000);
// VerifyDisk();
return 0;
}
int BmFF::InvalidateDisk(void)
{
UpdateInfo();
MakeMBR();
MakeFATBS();
memset(mWrMasterBootRecord, 0xff, sizeof(mWrMasterBootRecord));
WriteAll();
return 0;
}
bool BmFF::VerifyDisk(void)
{
int ret;
ret = OpenDevice(false);
if(ret != 0) return false;
ret = GetBlocks();
if(ret != 0) goto error;
AllocMem();
if(mEmmc == false)
{
ret = GetMBR();
if(ret != 0) goto error_mem;
}
ret = GetFATBS();
if(ret != 0) goto error_mem;
MakeMemDirectories();
if(mEmmc == false)
{
if(!VerifyMBR()) goto error_mem;
}
if(!VerifyFATBS()) goto error_mem;
if(!VerifyFAT()) goto error_mem;
if(!VerifyDirectories())
{
#if BMFF_RECOVER
mRecoverFlag = true;
RecoverDirectories();
if(!VerifyDirectories())
goto error_mem;
else
mRecovered = true;
#else
goto error_mem;
#endif
}
CloseDevice();
FreeMem();
return true;
error_mem:
FreeMem();
error:
CloseDevice();
return false;
}
void BmFF::CalcFat(void)
{
#ifdef WIN32
unsigned __int64 fatSectors = mBlocks - FIRST_SECTOR;
unsigned __int64 dataClusters1 = (((fatSectors - FAT_RESERVED_SECTORS) * SECTORS_PER_CLUSTER) - 4) /
((SECTORS_PER_CLUSTER * SECTORS_PER_CLUSTER) + 2);
unsigned __int64 sectorsPerFat = ((dataClusters1 + 2) * 4) / SECTOR_SIZE;
unsigned __int64 logFilesClusters = (LOG0_FILE_SIZE / CLUSTER_SIZE) + (LOG1_FILE_SIZE / CLUSTER_SIZE) + (LOG2_FILE_SIZE / CLUSTER_SIZE);
if((dataClusters1 + 2) * 4 % SECTOR_SIZE != 0)
++sectorsPerFat;
if(sectorsPerFat % SPF_UNIT != 0)
{
sectorsPerFat /= SPF_UNIT;
sectorsPerFat *= SPF_UNIT;
sectorsPerFat += SPF_UNIT;
}
unsigned long dataClusters2 = ((fatSectors - FAT_RESERVED_SECTORS - (sectorsPerFat * 2)) / SECTORS_PER_CLUSTER);
unsigned long dataSectors = dataClusters2 * SECTORS_PER_CLUSTER;
mPtTotalSectors = (unsigned long)(dataSectors + FAT_RESERVED_SECTORS + (sectorsPerFat * 2));
mSectorsPerFat = sectorsPerFat;
#else
unsigned long long fatSectors = mBlocks - FIRST_SECTOR;
unsigned long long dataClusters1 = ((fatSectors - FAT_RESERVED_SECTORS) * SECTORS_PER_CLUSTER - 4) /
(SECTORS_PER_CLUSTER * SECTORS_PER_CLUSTER + 2);
unsigned long long sectorsPerFat = (dataClusters1 + 2) * 4 / SECTOR_SIZE;
int logFilesClusters = (LOG0_FILE_SIZE / CLUSTER_SIZE) + (LOG1_FILE_SIZE / CLUSTER_SIZE) + (LOG2_FILE_SIZE / CLUSTER_SIZE);
if((dataClusters1 + 2) * 4 % SECTOR_SIZE != 0)
++sectorsPerFat;
if(sectorsPerFat % SPF_UNIT != 0)
{
sectorsPerFat /= SPF_UNIT;
sectorsPerFat *= SPF_UNIT;
sectorsPerFat += SPF_UNIT;
}
unsigned int dataClusters2 = (fatSectors - FAT_RESERVED_SECTORS - sectorsPerFat * 2) / SECTORS_PER_CLUSTER;
unsigned int dataSectors = dataClusters2 * SECTORS_PER_CLUSTER;
mPtTotalSectors = dataSectors + FAT_RESERVED_SECTORS + sectorsPerFat * 2;
mSectorsPerFat = sectorsPerFat;
#endif
mDataTotalClusters = dataClusters2;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// unsigned int dataSectors = mPtTotalSectors - FAT_RESERVED_SECTORS - mSectorsPerFat * 2;
// unsigned int dataClusters = dataSectors / SECTORS_PER_CLUSTER;
unsigned int directoryReservedClusters = 4 * MiB / CLUSTER_SIZE;
unsigned int logDirectoryFileClusters = (LOG0_FILE_SIZE + LOG1_FILE_SIZE + LOG2_FILE_SIZE) * 2 / CLUSTER_SIZE + 1;
unsigned int availableDataClusters = dataClusters2 - directoryReservedClusters - logDirectoryFileClusters - 1 - FREE_SPACE_CLUSTERS;
unsigned int totalEventFileClusters = 1LL * availableDataClusters * mEventPercent / 100;
unsigned int totalManualFileClusters = 1LL * availableDataClusters * mManualPercent / 100;
unsigned int totalParkingNormalFileClusters = 1LL * availableDataClusters * mParkingNormalPercent / 100;
unsigned int totalParkingEventFileClusters = 1LL * availableDataClusters * mParkingEventPercent / 100;
unsigned int totalNormalFileClusters;
mEventFiles = (totalEventFileClusters / (mEventFrontFileClusters + mEventRearFileClusters));
if(mEventRearFileClusters > 0)
mEventFiles *= 2;
mEventRecords = (mEventRearFileClusters > 0) ? mEventFiles / 2 : mEventFiles;
totalEventFileClusters = (mEventFrontFileClusters + mEventRearFileClusters) * mEventRecords;
mManualFiles = (totalManualFileClusters / (mManualFrontFileClusters + mManualRearFileClusters));
if(mManualRearFileClusters > 0)
mManualFiles *= 2;
mManualRecords = (mManualRearFileClusters > 0) ? mManualFiles / 2 : mManualFiles;
totalManualFileClusters = (mManualFrontFileClusters + mManualRearFileClusters) * mManualRecords;
if(mParkingNormalPercent > 0)
{
mParkingNormalFiles = (totalParkingNormalFileClusters / (mParkingFrontFileClusters + mParkingRearFileClusters));
if(mParkingRearFileClusters > 0)
mParkingNormalFiles *= 2;
mParkingNormalRecords = (mParkingRearFileClusters > 0) ? mParkingNormalFiles / 2 : mParkingNormalFiles;
totalParkingNormalFileClusters = (mParkingFrontFileClusters + mParkingRearFileClusters) * mParkingNormalRecords;
mParkingEventFiles = (totalParkingEventFileClusters / (mParkingFrontFileClusters + mParkingRearFileClusters));
if(mParkingRearFileClusters > 0)
mParkingEventFiles *= 2;
mParkingEventRecords = (mParkingRearFileClusters > 0) ? mParkingEventFiles / 2 : mParkingEventFiles;
totalParkingEventFileClusters = (mParkingFrontFileClusters + mParkingRearFileClusters) * mParkingEventRecords;
}
else
{
mParkingNormalFiles = 0;
mParkingNormalRecords = 0;
totalParkingNormalFileClusters = 0;
mParkingEventFiles = 0;
mParkingEventRecords = 0;
totalParkingEventFileClusters = 0;
}
totalNormalFileClusters = availableDataClusters - (totalEventFileClusters + totalManualFileClusters + totalParkingNormalFileClusters + totalParkingEventFileClusters);
mNormalFiles = (totalNormalFileClusters / (mNormalFrontFileClusters + mNormalRearFileClusters));
if(mNormalRearFileClusters > 0)
mNormalFiles *= 2;
mNormalRecords = (mNormalRearFileClusters > 0) ? mNormalFiles / 2 : mNormalFiles;
totalNormalFileClusters = (mNormalFrontFileClusters + mNormalRearFileClusters) * mNormalRecords;
mNormalDirectoryClusters = (mNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mNormalDirectoryClusters;
mEventDirectoryClusters = (mEventFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mEventFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mEventDirectoryClusters;
mManualDirectoryClusters = (mManualFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mManualFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mManualDirectoryClusters;
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
mParkingDirectoryClusters = 0;
mParkingNormalDirectoryClusters = (mParkingNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mParkingNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mParkingNormalDirectoryClusters;
mParkingEventDirectoryClusters = 0;
}
else
{
mParkingDirectoryClusters = 1;
mParkingNormalDirectoryClusters = (mParkingNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mParkingNormalFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mParkingNormalDirectoryClusters;
mParkingEventDirectoryClusters = (mParkingEventFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) / CLUSTER_SIZE;
if((mParkingEventFiles * 0x60 + 0x40 + DIRECTORY_OVERHEAD) % CLUSTER_SIZE != 0)
++mParkingEventDirectoryClusters;
}
}
else
{
mParkingDirectoryClusters = 0;
mParkingNormalDirectoryClusters = 0;
mParkingEventDirectoryClusters = 0;
}
mLogDirectoryStartCluster = mRootDirectoryStartCluster + mRootDirectoryClusters;
mLogFilesStartCluster = mLogDirectoryStartCluster + mLogDirectoryClusters;
mParkingDirectoryStartCluster = mLogFilesStartCluster + logFilesClusters;
mNormalDirectoryStartCluster = mParkingDirectoryStartCluster + mParkingDirectoryClusters;
mEventDirectoryStartCluster = mNormalDirectoryStartCluster + mNormalDirectoryClusters;
mManualDirectoryStartCluster = mEventDirectoryStartCluster + mEventDirectoryClusters;
mParkingNormalDirectoryStartCluster = mManualDirectoryStartCluster + mManualDirectoryClusters;
mParkingEventDirectoryStartCluster = mParkingNormalDirectoryStartCluster + mParkingNormalDirectoryClusters;
mRootDirectoryStartSector = FIRST_SECTOR + FAT_RESERVED_SECTORS + mSectorsPerFat * 2;
mLogDirectoryStartSector = mRootDirectoryStartSector + (mRootDirectoryClusters) * SECTORS_PER_CLUSTER;
mLogFilesStartSector = mLogDirectoryStartSector + (mLogDirectoryClusters) * SECTORS_PER_CLUSTER;
mParkingDirectoryStartSector = mLogFilesStartSector + (logFilesClusters) * SECTORS_PER_CLUSTER;
mNormalDirectoryStartSector = mParkingDirectoryStartSector + (mParkingDirectoryClusters) * SECTORS_PER_CLUSTER;
mEventDirectoryStartSector = mNormalDirectoryStartSector + (mNormalDirectoryClusters) * SECTORS_PER_CLUSTER;
mManualDirectoryStartSector = mEventDirectoryStartSector + (mEventDirectoryClusters) * SECTORS_PER_CLUSTER;
mParkingNormalDirectoryStartSector = mManualDirectoryStartSector + (mManualDirectoryClusters) * SECTORS_PER_CLUSTER;
mParkingEventDirectoryStartSector = mParkingNormalDirectoryStartSector + (mParkingNormalDirectoryClusters) * SECTORS_PER_CLUSTER;
if(!mNoPrintFlag) printf("DataSectors = %ld, DataClusters = %ld, SectorsPerFat = %d\n", dataSectors, dataClusters2, mSectorsPerFat);
if(!mNoPrintFlag) printf("AvailableDataClusters = %d, ScrapsClusters = %d\n", availableDataClusters,
availableDataClusters - (totalNormalFileClusters + totalEventFileClusters + totalManualFileClusters + totalParkingNormalFileClusters + totalParkingEventFileClusters));
if(!mNoPrintFlag) printf("NormalPercent = %d%%, EventPercent = %d%%, ManualPercent = %d%%, ParkingNormalPercent = %d%%, ParkingEventPercent = %d%%\n",
mNormalPercent, mEventPercent, mManualPercent, mParkingNormalPercent, mParkingEventPercent);
if(!mNoPrintFlag) printf("TotalNormalFileClusters = %d, TotalEventFileClusters = %d, TotalManualFileClusters = %d, TotalParkingNormalFileClusters = %d, TotalParkingEventFileClusters = %d\n",
totalNormalFileClusters, totalEventFileClusters, totalManualFileClusters, totalParkingNormalFileClusters, totalParkingEventFileClusters);
printf("NormalFiles = %d, EventFiles = %d, ManualFiles = %d, ParkingNormalFiles = %d, ParkingEventFiles = %d\n",
mNormalFiles, mEventFiles, mManualFiles, mParkingNormalFiles, mParkingEventFiles);
printf("NormalRecords = %d, EventRecords = %d, ManualRecords = %d, ParkingNormalRecords = %d, ParkingEventRecords = %d\n",
mNormalRecords,
mEventRecords,
mManualRecords,
mParkingNormalRecords,
mParkingEventRecords);
if(!mNoPrintFlag) printf("NormalDirectoryClusters = %d, EventDirectoryClusters = %d\n", mNormalDirectoryClusters, mEventDirectoryClusters);
if(!mNoPrintFlag) printf("RootDirectoryStartCluster = %d, clusters = %d\n", mRootDirectoryStartCluster, mRootDirectoryClusters);
if(!mNoPrintFlag) printf("LogDirectoryStartCluster = %d, clusters = %d\n", mLogDirectoryStartCluster, mLogDirectoryClusters);
if(!mNoPrintFlag) printf("LogFilesStartCluster = %d, clusters = %d\n", mLogFilesStartCluster, logFilesClusters);
if(!mNoPrintFlag) printf("ParkingDirectoryStartCluster = %d, clusters = %d\n", mParkingDirectoryStartCluster, mParkingDirectoryClusters);
if(!mNoPrintFlag) printf("NormalDirectoryStartCluster = %d, clusters = %d\n", mNormalDirectoryStartCluster, mNormalDirectoryClusters);
if(!mNoPrintFlag) printf("EventDirectoryStartCluster = %d, clusters = %d\n", mEventDirectoryStartCluster, mEventDirectoryClusters);
if(!mNoPrintFlag) printf("ManualDirectoryStartCluster = %d, clusters = %d\n", mManualDirectoryStartCluster, mManualDirectoryClusters);
if(!mNoPrintFlag) printf("ParkingNormalDirectoryStartCluster = %d, clusters = %d\n", mParkingNormalDirectoryStartCluster, mParkingNormalDirectoryClusters);
if(!mNoPrintFlag) printf("ParkingEventDirectoryStartCluster = %d, clusters = %d\n", mParkingEventDirectoryStartCluster, mParkingEventDirectoryClusters);
if(!mNoPrintFlag) printf("\n");
if(!mNoPrintFlag) printf("RootDirectoryStartSector = %d\n", mRootDirectoryStartSector);
if(!mNoPrintFlag) printf("LogDirectoryStartSector = %d\n", mLogDirectoryStartSector);
if(!mNoPrintFlag) printf("LogFilesStartSector = %d\n", mLogFilesStartSector);
if(!mNoPrintFlag) printf("ParkingDirectoryStartSector = %d\n", mParkingDirectoryStartSector);
if(!mNoPrintFlag) printf("NormalDirectoryStartSector = %d\n", mNormalDirectoryStartSector);
if(!mNoPrintFlag) printf("EventDirectoryStartSector = %d\n", mEventDirectoryStartSector);
if(!mNoPrintFlag) printf("ManualDirectoryStartSector = %d\n", mManualDirectoryStartSector);
if(!mNoPrintFlag) printf("ParkingNormalDirectoryStartSector = %d\n", mParkingNormalDirectoryStartSector);
if(!mNoPrintFlag) printf("ParkingEventDirectoryStartSector = %d\n", mParkingEventDirectoryStartSector);
}
void BmFF::AllocMem(void)
{
mMemFat = (unsigned int *)malloc(mSectorsPerFat * SECTOR_SIZE);
memset(mMemFat, 0, mSectorsPerFat * SECTOR_SIZE);
mMemFat[0] = 0x0ffffff8;
mMemFat[1] = 0xffffffff;
mCurrentFatOffset = mRootDirectoryStartCluster;
mMemRootDirectory = (char *)malloc(mRootDirectoryClusters * CLUSTER_SIZE);
memset(mMemRootDirectory, 0, mRootDirectoryClusters * CLUSTER_SIZE);
mMemLogDirectory = (char *)malloc(mLogDirectoryClusters * CLUSTER_SIZE);
memset(mMemLogDirectory, 0, mLogDirectoryClusters * CLUSTER_SIZE);
mMemNormalDirectory = (char *)malloc(mNormalDirectoryClusters * CLUSTER_SIZE);
memset(mMemNormalDirectory, 0, mNormalDirectoryClusters * CLUSTER_SIZE);
mMemEventDirectory = (char *)malloc(mEventDirectoryClusters * CLUSTER_SIZE);
memset(mMemEventDirectory, 0, mEventDirectoryClusters * CLUSTER_SIZE);
mMemManualDirectory = (char *)malloc(mManualDirectoryClusters * CLUSTER_SIZE);
memset(mMemManualDirectory, 0, mManualDirectoryClusters * CLUSTER_SIZE);
if(mParkingNormalPercent > 0)
{
mMemParkingDirectory = (char *)malloc(mParkingDirectoryClusters * CLUSTER_SIZE);
memset(mMemParkingDirectory, 0, mParkingDirectoryClusters * CLUSTER_SIZE);
mMemParkingNormalDirectory = (char *)malloc(mParkingNormalDirectoryClusters * CLUSTER_SIZE);
memset(mMemParkingNormalDirectory, 0, mParkingNormalDirectoryClusters * CLUSTER_SIZE);
mMemParkingEventDirectory = (char *)malloc(mParkingEventDirectoryClusters * CLUSTER_SIZE);
memset(mMemParkingEventDirectory, 0, mParkingEventDirectoryClusters * CLUSTER_SIZE);
}
else
{
mMemParkingDirectory = NULL;
mMemParkingNormalDirectory = NULL;
mMemParkingEventDirectory = NULL;
}
}
void BmFF::FreeMem(void)
{
free(mMemRootDirectory);
free(mMemLogDirectory);
free(mMemNormalDirectory);
free(mMemEventDirectory);
free(mMemManualDirectory);
if(mParkingNormalPercent > 0)
{
free(mMemParkingDirectory);
free(mMemParkingNormalDirectory);
free(mMemParkingEventDirectory);
}
}
int BmFF::OpenDevice(bool bWrite)
{
#ifdef _WIN32
// 포맷되어 있지 않은 경우 사용할 수 없음
/*
DWORD lpSectorsPerCluster = 0;
DWORD lpBytesPerSector = 0;
DWORD lpNumberOfFreeClusters = 0;
DWORD lpTotalNumberOfClusters = 0;
QString disk = "F:\\";
::GetDiskFreeSpace(reinterpret_cast<LPCWSTR>(disk.utf16()),&lpSectorsPerCluster,&lpBytesPerSector,&lpNumberOfFreeClusters,&lpTotalNumberOfClusters);
mBlocks = lpSectorsPerCluster * lpTotalNumberOfClusters;
*/
//qInfo() << "lpSectorsPerCluster:" << lpSectorsPerCluster << "lpTotalNumberOfClusters:" << lpTotalNumberOfClusters << "lpBytesPerSector:" << lpBytesPerSector << "lpNumberOfFreeClusters:" << lpNumberOfFreeClusters << __FUNCTION__;
// lpSectorsPerCluster: 64 lpNumberOfFreeClusters: 485606 BmFF::OpenDevice
if(mFd != NULL) {
CloseDevice();
}
// FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH
if(bWrite) {
mFd = ::CreateFile(
reinterpret_cast<LPCWSTR>(mDeviceName.utf16()),
GENERIC_WRITE,// | GENERIC_WRITE,
0,// | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
} else {
mFd = ::CreateFile(
reinterpret_cast<LPCWSTR>(mDeviceName.utf16()),
GENERIC_READ,// | GENERIC_WRITE,
FILE_SHARE_READ,// | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
}
if(mFd == INVALID_HANDLE_VALUE) {
return -1;
}
if(bWrite) {
//::ZeroMemory(&mOV, sizeof(OVERLAPPED));
// dismount output
if (!::DeviceIoControl(mFd, FSCTL_DISMOUNT_VOLUME,NULL, 0, NULL, 0, NULL, NULL)) {
return -1;
}
// lock output
if (!::DeviceIoControl(mFd, FSCTL_LOCK_VOLUME,NULL, 0, NULL, 0, NULL, NULL)) {
return -1;
}
}
#else // _WIN32
mFd = open64(mDeviceName.c_str(), O_RDWR);
if(mFd < 0)
{
printf("OpenDevice error...%s\n", mDeviceName.c_str());
return -1;
}
if(!mNoPrintFlag) printf("OpenDevice OK...%s\n", mDeviceName.c_str());
#endif // _WIN32
return 0;
}
void BmFF::CloseDevice(void)
{
#if _WIN32
if(mFd != INVALID_HANDLE_VALUE && mFd != NULL) {
::DeviceIoControl(mFd, FSCTL_UNLOCK_VOLUME,NULL, 0, NULL, 0, NULL, NULL);
::CloseHandle(mFd);
}
mFd = NULL;
#else // WIN32
fsync(mFd);
close(mFd);
#endif // WIN32
}
int BmFF::GetBlocks(void)
{
// 7,743,300
ioctl(mFd, BLKGETSIZE, &mBlocks);
printf("mblocks = %d(%dMiB)\n", mBlocks, (int)(1LL * mBlocks * SECTOR_SIZE / MiB));
if((mBlocks < MIN_SECTORS) || (mBlocks > MAX_SECTORS)) {
return -1;
}
CalcFat();
return 0;
}
int BmFF::GetBlocksFirst(void)
{
ioctl(mFd, BLKGETSIZE, &mBlocks);
printf("mblocks = %d(%dMiB)\n", mBlocks, (int)(1LL * mBlocks * SECTOR_SIZE / MiB));
if((mBlocks < MIN_SECTORS) || (mBlocks > MAX_SECTORS)) {
return -1;
}
return 0;
}
int BmFF::GetMBR(void)
{
int readed = read(mFd, mRdMasterBootRecord, SECTOR_SIZE);
if(readed != SECTOR_SIZE)
{
printf("read error : readed=%d\n", readed);
return -1;
}
//HexDump(mRdMasterBootRecord, SECTOR_SIZE);
if(ChkMBR() != 0)
{
printf("ChkMBR() error \n");
return -1;
}
if(ChkPT() != 0)
{
printf("ChkPT() error \n");
return -1;
}
// CalcFat();
if(!mNoPrintFlag) printf("serial number = 0x%08x\n", MBR_DISK_SERIAL_NUMBER(mRdMasterBootRecord));
if(!mNoPrintFlag) printf("FAT total sectors = %ld\n", mPtTotalSectors);
if(!mNoPrintFlag) printf("sectors per FAT = %d\n", mSectorsPerFat);
return 0;
}
int BmFF::GetFATBS(void)
{
loff_t offset = lseek64(mFd, ((loff_t)FIRST_SECTOR) * ((loff_t)SECTOR_SIZE), SEEK_SET);
if(offset < 0)
{
printf("GetFATBS()...Error: lseek()\n");
return -1;
}
int readed = read(mFd, mRdFat32BootSector, SECTOR_SIZE);
if(readed != SECTOR_SIZE)
{
printf("GetFATBS()...Error: read(). readed=%d, expected=%d\n", readed, SECTOR_SIZE);
return -1;
}
return 0;
}
int BmFF::GetFAT(void)
{
return 0;
}
int BmFF::UpdateInfo(void)
{
int ret;
ret = OpenDevice(false);
if(ret != 0) return -1;
ret = GetBlocks();
if(mEmmc == false)
{
if(ret == 0)
ret = GetMBR();
if(ret == 0)
ret = GetFAT();
}
CloseDevice();
return ret;
}
int BmFF::UpdateInfoFirst(void)
{
int ret;
ret = OpenDevice(false);
if(ret != 0) return -1;
ret = GetBlocksFirst();
if(mEmmc == false)
{
if(ret == 0)
ret = GetMBR();
if(ret == 0)
ret = GetFAT();
}
CloseDevice();
return ret;
}
void BmFF::HexDump(char *buff, int size)
{
for(int i = 0; i < size; ++i)
{
if(i % 16 == 0)
printf("\n0x%08x :", i);
else if(i % 4 == 0)
printf(",");
printf(" %02x", buff[i]);
}
printf("\n");
fflush(stdout);
}
int BmFF::ChkMBR(void)
{
if(MBR_SIGNATURE(mRdMasterBootRecord) != SIGNATURE)
{
printf("ChkMBR() error... SIGNATURE = %04x\n", (int)MBR_SIGNATURE(mRdMasterBootRecord));
return -1;
}
mSerialNumber = MBR_DISK_SERIAL_NUMBER(mRdMasterBootRecord);
return 0;
}
int BmFF::ChkPT(void)
{
// + 0x1be(446) + (0x10(16) * index)
// ((char*)(mbr) + 0x1be + (0x10 * (index)))
if(PT_ACTIVE_PARTITION_FLAG(mRdMasterBootRecord, 0) != ACTIVE_PARTITION_FLAG)
{
printf("ChkPT() error... ACTIVE_PARTITION_FLAG = 0x%02x\n", (int)PT_ACTIVE_PARTITION_FLAG(mRdMasterBootRecord, 0));
return -1;
}
if(PT_FILE_SYSTEM_ID(mRdMasterBootRecord, 0) != FILE_SYSTEM_ID)
{
printf("ChkPT() error... FILE_SYSTEM_ID = 0x%02x\n", (int)PT_FILE_SYSTEM_ID(mRdMasterBootRecord, 0));
return -1;
}
if(PT_FIRST_SECTOR(mRdMasterBootRecord, 0) != FIRST_SECTOR)
{
printf("ChkPT() error... FIRST_SECTOR = %d\n", (int)PT_FIRST_SECTOR(mRdMasterBootRecord, 0));
return -1;
}
return 0;
}
char BmFF::GetFileSystem()
{
return (char)PT_FILE_SYSTEM_ID(mRdMasterBootRecord, 0);
}
void BmFF::MakeMBR(void)
{
memset(mWrMasterBootRecord, 0, sizeof(mWrMasterBootRecord));
// 1B8 -> OK
MBR_DISK_SERIAL_NUMBER(mWrMasterBootRecord) = (mSerialNumber == BM_FACTORY_SERIAL_NUMBER || mMakeFactoryAging) ? BM_FACTORY_SERIAL_NUMBER : BM_SERIAL_NUMBER;
// 1BE + 4 = 1C2:C -> OK
PT_FILE_SYSTEM_ID(mWrMasterBootRecord, 0) = FILE_SYSTEM_ID;
// 1BE + 8 = 1C6: 0x800=2048 -> OK
PT_FIRST_SECTOR(mWrMasterBootRecord, 0) = FIRST_SECTOR;
// PT_TOTAL_SECTORS(mWrMasterBootRecord, 0) = (unsigned int)mBlocks;
// 1BE + 12 = 1CA:7,742,464 ??? 7,741,248
PT_TOTAL_SECTORS(mWrMasterBootRecord, 0) = (unsigned int)mPtTotalSectors; // jykang 20200609
// 1FE = AA55
MBR_SIGNATURE(mWrMasterBootRecord) = SIGNATURE;
}
void BmFF::MakeFATBS(void)
{
char fatbs[512] =
{
// 0xEB, 0x58, 0x90, 0x64, 0x65, 0x64, 0x69, 0x61, 0x68, 0x69, 0x6C, 0x00, 0x02, 0x80, 0x80, 0x00,
0xEB, 0x58, 0x90, 0x6D, 0x6B, 0x64, 0x6F, 0x73, 0x66, 0x73, 0x00, 0x00, 0x02, 0x80, 0x80, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0x00, 0x00, 0x9E, 0x3B, 0x80, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x29, 0xEE, 0xEE, 0xEE, 0xEE, 0x44, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x46, 0x41, 0x54, 0x33, 0x32, 0x20, 0x20, 0x20, 0x0E, 0x1F, 0xBE, 0x77, 0x7C, 0xAC,
0x22, 0xC0, 0x74, 0x0B, 0x56, 0xB4, 0x0E, 0xBB, 0x07, 0x00, 0xCD, 0x10, 0x5E, 0xEB, 0xF0, 0x32,
0xE4, 0xCD, 0x16, 0xCD, 0x19, 0xEB, 0xFE, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6E,
0x6F, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6F, 0x6F, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x64, 0x69,
0x73, 0x6B, 0x2E, 0x20, 0x20, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6E, 0x73, 0x65,
0x72, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6F, 0x6F, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x66, 0x6C,
0x6F, 0x70, 0x70, 0x79, 0x20, 0x61, 0x6E, 0x64, 0x0D, 0x0A, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20,
0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61,
0x67, 0x61, 0x69, 0x6E, 0x20, 0x2E, 0x2E, 0x2E, 0x20, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
};
fatbs[13] = SECTORS_PER_CLUSTER;
memcpy(mWrFat32BootSector, fatbs, sizeof(mWrFat32BootSector));
BS_TOTAL_SECTORS(mWrFat32BootSector) = (unsigned int)mPtTotalSectors;
BS_SECTORS_PER_FAT(mWrFat32BootSector) = (unsigned int)mSectorsPerFat;
}
void BmFF::MakeSIS(void)
{
memset(mWrSystemInformationSector, 0, sizeof(mWrSystemInformationSector));
SIS_SIGNATURE_FIRST(mWrSystemInformationSector) = 0x41615252;
SIS_SIGNATURE_MIDDLE(mWrSystemInformationSector) = 0x61417272;
SIS_LAST_FREE_CLUSTER(mWrSystemInformationSector) = mDataTotalClusters - mCurrentFatOffset + mRootDirectoryStartCluster;
SIS_LAST_ALLOCATED_CLUSTER(mWrSystemInformationSector) = 0xffffffff;
SIS_SIGNATURE_LAST(mWrSystemInformationSector) = 0xaa550000;
}
int BmFF::WriteAll(void)
{
ssize_t written;
loff_t offset;
if(OpenDevice(true) != 0) {
printf("OPEN(WRITE) FAILED");
return -1;
}
// 강제로 다시 이동???
//lseek64(mFd,0,SEEK_SET);
if(mEmmc == false)
{
written = write(mFd, mWrMasterBootRecord, sizeof(mWrMasterBootRecord)); // ,&mOV
printf("BS SIZE: %d 1476\n",sizeof(mWrFat32BootSector));
if(written != sizeof(mWrMasterBootRecord))
{
printf("MBR write error...\n");
return -1;
}
if(!mNoPrintFlag) printf("MBR write OK...\n");
usleep(1);
ZeroBlocks(1, FIRST_SECTOR - 1);
ZeroBlocks(mBlocks - 128, 128);
usleep(1);
}
printf("BS SIZE: %d 1489\n",sizeof(mWrFat32BootSector));
// 2048
offset = lseek64(mFd, ((loff_t)FIRST_SECTOR) * SECTOR_SIZE, SEEK_SET);
if(offset != (off_t)FIRST_SECTOR * SECTOR_SIZE)
{
printf("lseek error...offset=%lld\n", ((off_t)FIRST_SECTOR) * SECTOR_SIZE);
goto error;
}
//printf("BS SIZE: %d %d 1498\n",sizeof(mWrFat32BootSector),::SetFilePointer(mFd,0,NULL,FILE_CURRENT));
written = write(mFd, mWrFat32BootSector, sizeof(mWrFat32BootSector));// ,&mOV
if(written != sizeof(mWrFat32BootSector))
{
printf("FATBS1 write error %d != %d...\n",written,SECTOR_SIZE);
goto error;
}
usleep(1);
// written = write(mFd, mWrSystemInformationSector, sizeof(mWrSystemInformationSector));
// if(written != sizeof(mWrSystemInformationSector))
// {
// printf("SIS write error...\n");
// goto error;
// }
offset = lseek64(mFd, (off_t)FIRST_SECTOR * SECTOR_SIZE + (loff_t)FAT_BOOT_SECTOR_COPY_POSITION * SECTOR_SIZE, SEEK_SET);
if(offset != (loff_t)FIRST_SECTOR * SECTOR_SIZE + (loff_t)FAT_BOOT_SECTOR_COPY_POSITION * SECTOR_SIZE)
{
printf("lseek error...offset=%lld\n", (loff_t)FIRST_SECTOR * SECTOR_SIZE + (loff_t)FAT_BOOT_SECTOR_COPY_POSITION * SECTOR_SIZE);
goto error;
}
written = write(mFd, mWrFat32BootSector, sizeof(mWrFat32BootSector)); // ,&mOV
if(written != sizeof(mWrFat32BootSector))
{
printf("FATBS2 write error...\n");
goto error;
}
usleep(1);
WriteDirectories();
MakeSIS();
offset = lseek64(mFd, (loff_t)(FIRST_SECTOR + 1) * SECTOR_SIZE, SEEK_SET);
if(offset != (loff_t)(FIRST_SECTOR + 1) * SECTOR_SIZE)
{
printf("lseek error...offset=%lld\n", (loff_t)(FIRST_SECTOR + 1) * SECTOR_SIZE);
goto error;
}
written = write(mFd, mWrSystemInformationSector, sizeof(mWrSystemInformationSector)); // ,&mOV
if(written != sizeof(mWrSystemInformationSector))
{
printf("SIS write error...\n");
goto error;
}
usleep(1);
printf("Free Clusters = %d\n", SIS_LAST_FREE_CLUSTER(mWrSystemInformationSector));
CloseDevice();
ForceFlush();
printf("Write OK\n");
return 0;
error:
CloseDevice();
printf("Write FAIL\n");
return -1;
}
void BmFF::MakeMemDirectories(void)
{
MakeRootDirectory();
if(!mMstarPark)
if(mParkingNormalPercent > 0)
MakeParkingDirectory();
#if (MODEL_CONFIG == BV3000)
MakeRecordDirectory(mMemNormalDirectory, mNormalDirectoryStartCluster,
".NORM90925-%06dW.TMP", "N%06dWTMP", ".NORM90925-%06dI.TMP", "N%06dITMP",
mNormalRecords, mNormalFrontFileClusters, mNormalRearFileClusters, 0);
MakeRecordDirectory(mMemEventDirectory, mEventDirectoryStartCluster,
".EVEN90925-%06dW.TMP", "E%06dWTMP", ".EVEN90925-%06dI.TMP", "E%06dITMP",
mEventRecords, mEventFrontFileClusters, mEventRearFileClusters, 0);
MakeRecordDirectory(mMemManualDirectory, mManualDirectoryStartCluster,
".MANU90925-%06dW.TMP", "M%06dWTMP", ".MANU90925-%06dI.TMP", "M%06dITMP",
mManualRecords, mManualFrontFileClusters, mManualRearFileClusters, 0);
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
MakeRecordDirectory(mMemParkingNormalDirectory, mParkingNormalDirectoryStartCluster,
".PARK90925-%06dW.TMP", "P%06dWTMP", ".PARK90925-%06dI.TMP", "P%06dITMP",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters, 0);
}
else
{
MakeRecordDirectory(mMemParkingNormalDirectory, mParkingNormalDirectoryStartCluster,
".PNOR90925-%06dW.TMP", "P%06dWTMP", ".PNOR90925-%06dI.TMP", "P%06dITMP",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters, mParkingDirectoryStartCluster);
MakeRecordDirectory(mMemParkingEventDirectory, mParkingEventDirectoryStartCluster,
".PEVE90925-%06dW.TMP", "P%06dWTMP", ".PEVE90925-%06dI.TMP", "P%06dITMP",
mParkingEventRecords, mParkingFrontFileClusters, mParkingRearFileClusters, mParkingDirectoryStartCluster);
}
}
#else
MakeRecordDirectory(mMemNormalDirectory, mNormalDirectoryStartCluster,
".NORM90925-%06dW.TMP", "N%06dWTMP", ".NORM90925-%06dR.TMP", "N%06dRTMP",
mNormalRecords, mNormalFrontFileClusters, mNormalRearFileClusters, 0);
MakeRecordDirectory(mMemEventDirectory, mEventDirectoryStartCluster,
".EVEN90925-%06dW.TMP", "E%06dWTMP", ".EVEN90925-%06dR.TMP", "E%06dRTMP",
mEventRecords, mEventFrontFileClusters, mEventRearFileClusters, 0);
if(mManualPercent > 0)
{
MakeRecordDirectory(mMemManualDirectory, mManualDirectoryStartCluster,
".MANU90925-%06dW.TMP", "M%06dWTMP", ".MANU90925-%06dR.TMP", "M%06dRTMP",
mManualRecords, mManualFrontFileClusters, mManualRearFileClusters, 0);
}
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
MakeRecordDirectory(mMemParkingNormalDirectory, mParkingNormalDirectoryStartCluster,
".PARK90925-%06dW.TMP", "P%06dWTMP", ".PARK90925-%06dR.TMP", "P%06dRTMP",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters, 0);
}
else
{
MakeRecordDirectory(mMemParkingNormalDirectory, mParkingNormalDirectoryStartCluster,
".PNOR90925-%06dW.TMP", "P%06dWTMP", ".PNOR90925-%06dR.TMP", "P%06dRTMP",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters, mParkingDirectoryStartCluster);
MakeRecordDirectory(mMemParkingEventDirectory, mParkingEventDirectoryStartCluster,
".PEVE90925-%06dW.TMP", "P%06dWTMP", ".PEVE90925-%06dR.TMP", "P%06dRTMP",
mParkingEventRecords, mParkingFrontFileClusters, mParkingRearFileClusters, mParkingDirectoryStartCluster);
}
}
#endif
}
int BmFF::WriteDirectories(void)
{
int ret;
off_t fatStartSector = (off_t)(FIRST_SECTOR + FAT_RESERVED_SECTORS);
AllocMem();
MakeMemDirectories();
if(!mRecoverFlag)
ret = WriteSectors(mMemRootDirectory, mRootDirectoryStartSector, mRootDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemLogDirectory, mLogDirectoryStartSector, mLogDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
if(!mMstarPark)
if(mParkingNormalPercent > 0)
ret = WriteSectors(mMemParkingDirectory, mParkingDirectoryStartSector, mParkingDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemNormalDirectory, mNormalDirectoryStartSector, mNormalDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemEventDirectory, mEventDirectoryStartSector, mEventDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemManualDirectory, mManualDirectoryStartSector, mManualDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
{
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
ret = WriteSectors(mMemParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
}
else
{
ret = WriteSectors(mMemParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
ret = WriteSectors(mMemParkingEventDirectory, mParkingEventDirectoryStartSector, mParkingEventDirectoryClusters * SECTORS_PER_CLUSTER);
}
}
}
if(ret == 0)
ret = WriteSectors((char*)mMemFat, fatStartSector, mSectorsPerFat);
if(ret == 0)
ret = WriteSectors((char*)mMemFat, fatStartSector + mSectorsPerFat, mSectorsPerFat);
FreeMem();
return ret;
}
void BmFF::MakeRootDirectory(void)
{
int rootDirectorySize = mRootDirectoryClusters * CLUSTER_SIZE;
char fileContext[] =
{
0x4C, 0x4F, 0x47, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x64, 0x40, 0x13,
0x39, 0x4F, 0x39, 0x4F, 0x00, 0x00, 0x40, 0x13, 0x39, 0x4F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};
int offsetByParking = (!mMstarPark && mParkingNormalPercent > 0) ? 0x20 : 0;
AddFatElement(mMemFat, mRootDirectoryClusters);
// mLogDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, LOG_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mLogDirectoryStartCluster);
memcpy(mMemRootDirectory + offsetByParking, fileContext, 0x20);
AddFatElement(mMemFat, mLogDirectoryClusters);
MakeLogDirectory();
if(!mMstarPark)
if(mParkingNormalPercent > 0)
{
// mParkingDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, PARKING_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mParkingDirectoryStartCluster);
memcpy(mMemRootDirectory, fileContext, 0x20);
AddFatElement(mMemFat, mParkingDirectoryClusters);
}
// mNormalDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, NORMAL_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mNormalDirectoryStartCluster);
memcpy(mMemRootDirectory + offsetByParking + 0x20, fileContext, 0x20);
AddFatElement(mMemFat, mNormalDirectoryClusters);
// mEventDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, EVENT_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mEventDirectoryStartCluster);
memcpy(mMemRootDirectory + offsetByParking + 0x40, fileContext, 0x20);
AddFatElement(mMemFat, mEventDirectoryClusters);
if(mManualPercent > 0)
{
// mManualDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, MANUAL_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mManualDirectoryStartCluster);
memcpy(mMemRootDirectory + offsetByParking + 0x60, fileContext, 0x20);
AddFatElement(mMemFat, mManualDirectoryClusters);
}
if(mMstarPark)
if(mParkingNormalPercent > 0)
{
// mParkingDirectoryStartCluster = mCurrentFatOffset;
SetDirFileName(fileContext, PARKING_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mParkingNormalDirectoryStartCluster);
memcpy(mMemRootDirectory + offsetByParking + 0x80, fileContext, 0x20);
AddFatElement(mMemFat, mParkingNormalDirectoryClusters);
}
}
void BmFF::MakeLogDirectory(void)
{
int log0FileClusters = LOG0_FILE_SIZE / CLUSTER_SIZE;
int log1FileClusters = LOG1_FILE_SIZE / CLUSTER_SIZE;
int log2FileClusters = LOG2_FILE_SIZE / CLUSTER_SIZE;
char defautlDirectoryContext[0x20] =
{
0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x63, 0x52,
0x3A, 0x4F, 0x3A, 0x4F, 0x54, 0x00, 0x63, 0x52, 0x3A, 0x4F, 0xB4, 0x22, 0x00, 0x00, 0x00, 0x00
};
char fileContext[0x20] =
{
0x53, 0x59, 0x53, 0x54, 0x45, 0x4D, 0x31, 0x20, 0x4C, 0x4F, 0x47, 0x20, 0x00, 0x64, 0x4D, 0x44,
0x39, 0x4F, 0x39, 0x4F, 0x00, 0x00, 0x4D, 0x44, 0x39, 0x4F, 0x15, 0x00, 0x53, 0x00, 0x00, 0x00
};
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ". ");
SetDirFirstCluster(defautlDirectoryContext, mLogDirectoryStartCluster);
memcpy(mMemLogDirectory, defautlDirectoryContext, 0x20);
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ".. ");
SetDirFirstCluster(defautlDirectoryContext, 0);
memcpy(mMemLogDirectory + 0x20, defautlDirectoryContext, 0x20);
SetDirFileAttribute(fileContext, 0x20);
SetDirFileName(fileContext, LOG_SYSTEM0_FILE);
SetDirFileSize(fileContext, LOG0_FILE_SIZE);
SetDirFirstCluster(fileContext, mCurrentFatOffset);
AddFatElement(mMemFat, log0FileClusters);
memcpy(mMemLogDirectory + 0x40, fileContext, 0x20);
SetDirFileAttribute(fileContext, 0x20);
SetDirFileName(fileContext, LOG_SYSTEM1_FILE);
SetDirFileSize(fileContext, LOG1_FILE_SIZE);
SetDirFirstCluster(fileContext, mCurrentFatOffset);
AddFatElement(mMemFat, log1FileClusters);
memcpy(mMemLogDirectory + 0x60, fileContext, 0x20);
SetDirFileAttribute(fileContext, 0x20);
SetDirFileName(fileContext, LOG_SYSTEM2_FILE);
SetDirFileSize(fileContext, LOG2_FILE_SIZE);
SetDirFirstCluster(fileContext, mCurrentFatOffset);
AddFatElement(mMemFat, log2FileClusters);
memcpy(mMemLogDirectory + 0x80, fileContext, 0x20);
// SetDirFileAttribute(fileContext, 0x20);
// SetDirFileName(fileContext, LOG_RECORD1_FILE);
// SetDirFileSize(fileContext, LOG_FILE_SIZE);
// SetDirFirstCluster(fileContext, mCurrentFatOffset);
// AddFatElement(mMemFat, logFileClusters);
// memcpy(mMemLogDirectory + 0x80, fileContext, 0x20);
// SetDirFileAttribute(fileContext, 0x20);
// SetDirFileName(fileContext, LOG_RECORD2_FILE);
// SetDirFileSize(fileContext, LOG_FILE_SIZE);
// SetDirFirstCluster(fileContext, mCurrentFatOffset);
// AddFatElement(mMemFat, logFileClusters);
// memcpy(mMemLogDirectory + 0xa0, fileContext, 0x20);
// SetDirFileAttribute(fileContext, 0x20);
// SetDirFileName(fileContext, PARAM_FILE);
// SetDirFileSize(fileContext, LOG_FILE_SIZE);
// SetDirFirstCluster(fileContext, mCurrentFatOffset);
// AddFatElement(mMemFat, logFileClusters);
// memcpy(mMemLogDirectory + 0xc0, fileContext, 0x20);
}
void BmFF::MakeParkingDirectory(void)
{
int parkingDirectorySize = mParkingDirectoryClusters * CLUSTER_SIZE;
char defautlDirectoryContext[0x20] =
{
0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x63, 0x52,
0x3A, 0x4F, 0x3A, 0x4F, 0x54, 0x00, 0x63, 0x52, 0x3A, 0x4F, 0xB4, 0x22, 0x00, 0x00, 0x00, 0x00
};
char fileContext[0x20] =
{
0x53, 0x59, 0x53, 0x54, 0x45, 0x4D, 0x31, 0x20, 0x4C, 0x4F, 0x47, 0x20, 0x00, 0x64, 0x4D, 0x44,
0x39, 0x4F, 0x39, 0x4F, 0x00, 0x00, 0x4D, 0x44, 0x39, 0x4F, 0x15, 0x00, 0x53, 0x00, 0x00, 0x00
};
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ". ");
SetDirFirstCluster(defautlDirectoryContext, mParkingDirectoryStartCluster);
memcpy(mMemParkingDirectory, defautlDirectoryContext, 0x20);
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ".. ");
SetDirFirstCluster(defautlDirectoryContext, 0);
memcpy(mMemParkingDirectory + 0x20, defautlDirectoryContext, 0x20);
SetDirFileName(fileContext, PARKING_NORMAL_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mParkingNormalDirectoryStartCluster);
memcpy(mMemParkingDirectory + 0x40, fileContext, 0x20);
AddFatElement(mMemFat, mParkingNormalDirectoryClusters);
SetDirFileName(fileContext, PARKING_EVENT_DIRECTORY);
SetDirFileAttribute(fileContext, 0x10);
SetDirFileSize(fileContext, 0);
SetDirFirstCluster(fileContext, mParkingEventDirectoryStartCluster);
memcpy(mMemParkingDirectory + 0x60, fileContext, 0x20);
AddFatElement(mMemFat, mParkingEventDirectoryClusters);
}
void BmFF::MakeRecordDirectory(char *data, int directoryStartCluster,
const char *fileFullNameFront, const char *fileName83Front, const char *fileFullNameRear, const char *fileName83Rear,
int nRecords, int frontFileClusters, int rearFileClusters, int parentStartCluster)
{
char defautlDirectoryContext[0x20] =
{
0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x63, 0x52,
0x3A, 0x4F, 0x3A, 0x4F, 0x54, 0x00, 0x63, 0x52, 0x3A, 0x4F, 0xB4, 0x22, 0x00, 0x00, 0x00, 0x00
};
char fileContext[0x60] =
{
0x42, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x46, 0x00, 0x0F, 0x00, 0xDC, 0x2E, 0x00,
0x4D, 0x00, 0x4F, 0x00, 0x56, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0x01, 0x2E, 0x00, 0x4F, 0x00, 0x52, 0x00, 0x4D, 0x00, 0x31, 0x00, 0x0F, 0x00, 0xDC, 0x39, 0x00,
0x30, 0x00, 0x39, 0x00, 0x32, 0x00, 0x35, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00,
0x4F, 0x52, 0x4D, 0x31, 0x39, 0x30, 0x7E, 0x31, 0x4D, 0x4F, 0x56, 0x22, 0x00, 0x64, 0x04, 0x43,
0x39, 0x4F, 0x39, 0x4F, 0x54, 0x00, 0x04, 0x43, 0x39, 0x4F, 0xB4, 0x22, 0x20, 0x00, 0x00, 0x00
};
int i;
char ffn[32];
char fn83[16];
unsigned int frontFileSize = frontFileClusters * CLUSTER_SIZE;
unsigned int rearFileSize = rearFileClusters * CLUSTER_SIZE;
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ". ");
SetDirFirstCluster(defautlDirectoryContext, directoryStartCluster);
memcpy(data, defautlDirectoryContext, 0x20);
data += 0x20;
SetDirFileAttribute(defautlDirectoryContext, 0x10);
SetDirFileName(defautlDirectoryContext, ".. ");
SetDirFirstCluster(defautlDirectoryContext, parentStartCluster);
memcpy(data, defautlDirectoryContext, 0x20);
data += 0x20;
for(i = 0; i < nRecords; ++i)
{
string backup_file_name = "";
sprintf(ffn, fileFullNameFront, i);
sprintf(fn83, fileName83Front, i);
if(mFormatFlag)
WriteFileName(ffn, mCurrentFatOffset);
else if(mRecoverFlag)
backup_file_name = ReadFileName(mCurrentFatOffset);
if(backup_file_name.empty())
{
SetDirFileNameLong(fileContext, fn83, ffn);
SetDirFileAttributeLong(fileContext, /*0x22*/0x20);
}
else
{
SetDirFileNameLong(fileContext, fn83, backup_file_name.c_str());
SetDirFileAttributeLong(fileContext, 0x20);
printf("Recover file name front(%d)...%s\n", i, backup_file_name.c_str());
}
SetDirFileSizeLong(fileContext, frontFileSize);
SetDirFirstClusterLong(fileContext, mCurrentFatOffset);
AddFatElement(mMemFat, frontFileClusters);
memcpy(data, fileContext, 0x60);
data += 0x60;
// HexDump(fileContext, 0x60);
if(mFlushStartOffset == 0)
mFlushStartOffset = mCurrentFatOffset;
if(rearFileClusters > 0)
{
backup_file_name = "";
sprintf(ffn, fileFullNameRear, i);
sprintf(fn83, fileName83Rear, i);
if(mFormatFlag)
WriteFileName(ffn, mCurrentFatOffset);
else if(mRecoverFlag)
backup_file_name = ReadFileName(mCurrentFatOffset);
if(backup_file_name.empty())
{
SetDirFileNameLong(fileContext, fn83, ffn);
SetDirFileAttributeLong(fileContext, /*0x22*/0x20);
}
else
{
SetDirFileNameLong(fileContext, fn83, backup_file_name.c_str());
SetDirFileAttributeLong(fileContext, 0x20);
printf("Recover file name rear(%d)...%s\n", i, backup_file_name.c_str());
}
SetDirFileAttributeLong(fileContext, 0x22);
SetDirFileSizeLong(fileContext, rearFileSize);
SetDirFirstClusterLong(fileContext, mCurrentFatOffset);
AddFatElement(mMemFat, rearFileClusters);
memcpy(data, fileContext, 0x60);
data += 0x60;
}
}
}
int BmFF::WriteSectors(char *data, unsigned int startSector, unsigned int sectors)
{
ssize_t written;
loff_t offset;
loff_t start = ((loff_t)startSector) * SECTOR_SIZE;
// unsigned int size = sectors * SECTOR_SIZE;
int i;
offset = lseek64(mFd, start, SEEK_SET);
if(offset != start)
{
printf("WriteSectors lseek error...start sector=%u, nsectors=%u to:%lld seek:%lld \n", startSector, sectors,start,offset);
return -1;
}
for(i = 0; i < sectors; ++i)
{
written = write(mFd, data + i * SECTOR_SIZE, SECTOR_SIZE); // ,&mOV
if(written != SECTOR_SIZE)
{
printf("WriteSectors write error...start sector=%u, nsectors=%u\n", startSector, sectors);
return -1;
}
usleep(1);
}
// if(!mNoPrintFlag) printf("WriteSectors OK. start sector=%u, nsectors=%u\n", startSector, sectors);
return 0;
}
void BmFF::SetFatElement(unsigned int *pFatBuff, unsigned int startCluster, int size)
{
for(int i = 0; i < (size - 1); ++i)
{
pFatBuff[startCluster + i] = startCluster + i + 1;
}
pFatBuff[startCluster + size - 1] = 0x0ffffff8;
}
void BmFF::AddFatElement(unsigned int *pFatBuff, int size)
{
for(int i = 0; i < (size - 1); ++i)
{
pFatBuff[mCurrentFatOffset + i] = mCurrentFatOffset + i + 1;
}
pFatBuff[mCurrentFatOffset + size - 1] = 0x0ffffff8;
mCurrentFatOffset += size;
}
void BmFF::SetDirFirstCluster(char *pDirBuff, unsigned int cluster)
{
unsigned short highWord = (cluster >> 16) & 0xffff;
unsigned short lowWord = cluster & 0xffff;
*(unsigned short*)(pDirBuff + 0x14) = highWord;
*(unsigned short*)(pDirBuff + 0x1A) = lowWord;
}
void BmFF::SetDirFirstClusterLong(char *pDirBuff, unsigned int cluster)
{
unsigned short highWord = (cluster >> 16) & 0xffff;
unsigned short lowWord = cluster & 0xffff;
*(unsigned short*)(pDirBuff + 0x54) = highWord;
*(unsigned short*)(pDirBuff + 0x5A) = lowWord;
}
void BmFF::SetDirFileAttribute(char *pDirBuff, unsigned char attribute)
{
pDirBuff[0xb] = attribute;
}
void BmFF::SetDirFileAttributeLong(char *pDirBuff, unsigned char attribute)
{
pDirBuff[0x4b] = attribute;
}
void BmFF::SetDirFileSize(char *pDirBuff, unsigned int filesize)
{
*(unsigned int*)(pDirBuff + 0x1C) = filesize;
}
void BmFF::SetDirFileSizeLong(char *pDirBuff, unsigned int filesize)
{
*(unsigned int*)(pDirBuff + 0x5C) = filesize;
}
void BmFF::SetDirFileName(char *pDirBuff, const char *fileName83)
{
memcpy(pDirBuff, fileName83, 11);
}
void BmFF::SetDirFileNameLong(char *pDirBuff, const char *fileName83, const char *fileFullName)
{
unsigned char checksum = FileNameChecksum(fileName83);
char ffn[26];
memset(ffn, 0xff, sizeof(ffn));
memcpy(ffn, fileFullName, strlen(fileFullName) + 1);
pDirBuff[0x0d] = checksum;
pDirBuff[0x2d] = checksum;
memcpy(pDirBuff + 0x40, fileName83, 11);
UTF8CharCopy(pDirBuff + 0x21, ffn, 5);
UTF8CharCopy(pDirBuff + 0x2e, ffn + 5, 6);
UTF8CharCopy(pDirBuff + 0x3c, ffn + 5 + 6, 2);
UTF8CharCopy(pDirBuff + 0x1, ffn + 5 + 6 + 2, 5);
UTF8CharCopy(pDirBuff + 0xe, ffn + 5 + 6 + 2 + 5, 6);
UTF8CharCopy(pDirBuff + 0x1c, ffn + 5 + 6 + 2 + 5 + 6, 2);
}
void BmFF::UTF8CharCopy(char *target_u, const char *source_c, int size)
{
for(int i = 0; i < size; ++i)
{
if(*source_c != 0xff)
{
*target_u++ = *source_c++;
*target_u++ = 0;
}
else
{
*target_u++ = *source_c++;
*target_u++ = 0xff;
}
}
}
void BmFF::CharUTF8Copy(char *target_c, const char *source_u, int size)
{
for(int i = 0; i < size; ++i)
{
*target_c++ = *source_u++;
source_u++;
}
}
void BmFF::GetDirFirstCluster(char *pDirBuff, unsigned int &cluster)
{
unsigned short highWord = (cluster >> 16) & 0xffff;
unsigned short lowWord = cluster & 0xffff;
highWord = *(unsigned short*)(pDirBuff + 0x14);
lowWord = *(unsigned short*)(pDirBuff + 0x1A);
cluster = (((unsigned int)highWord) << 16) + lowWord;
}
void BmFF::GetDirFirstClusterLong(char *pDirBuff, unsigned int &cluster)
{
unsigned short highWord = (cluster >> 16) & 0xffff;
unsigned short lowWord = cluster & 0xffff;
highWord = *(unsigned short*)(pDirBuff + 0x54);
lowWord = *(unsigned short*)(pDirBuff + 0x5A);
cluster = (((unsigned int)highWord) << 16) + lowWord;
}
void BmFF::GetDirFileAttribute(char *pDirBuff, unsigned char &attribute)
{
attribute = pDirBuff[0xb];
}
void BmFF::GetDirFileAttributeLong(char *pDirBuff, unsigned char &attribute)
{
attribute = pDirBuff[0x4b];
}
void BmFF::GetDirFileSize(char *pDirBuff, unsigned int &filesize)
{
filesize = *(unsigned int*)(pDirBuff + 0x1C);
}
void BmFF::GetDirFileSizeLong(char *pDirBuff, unsigned int &filesize)
{
filesize = *(unsigned int*)(pDirBuff + 0x5C);
// filesize = (*(pDirBuff + 0x5C)) +
// (*(pDirBuff + 0x5D) << 8) +
// (*(pDirBuff + 0x5E) << 16) +
// (*(pDirBuff + 0x5F) << 24);
}
void BmFF::GetDirFileName(char *pDirBuff, char *fileName83)
{
memcpy(fileName83, pDirBuff, 11);
fileName83[11] = 0;
}
void BmFF::GetDirFileNameLong(char *pDirBuff, char *fileName83, char *fileFullName)
{
char ffn[32];
memset(ffn, 0, sizeof(ffn));
memcpy(fileName83, pDirBuff + 0x40, 11);
fileName83[11] = 0;
CharUTF8Copy(ffn, pDirBuff + 0x21, 5);
CharUTF8Copy(ffn + 5, pDirBuff + 0x2e, 6);
CharUTF8Copy(ffn + 5 + 6, pDirBuff + 0x3c, 2);
CharUTF8Copy(ffn + 5 + 6 + 2, pDirBuff + 0x1, 5);
CharUTF8Copy(ffn + 5 + 6 + 2 + 5, pDirBuff + 0xe, 6);
CharUTF8Copy(ffn + 5 + 6 + 2 + 5 + 6, pDirBuff + 0x1c, 2);
*(ffn + 5 + 6 + 2 + 5 + 6 + 2) = 0;
strcpy(fileFullName, ffn);
}
unsigned char BmFF::FileNameChecksum(const char *fileName83)
{
int i;
unsigned char sum = 0;
for (i = 11; i; i--)
sum = ((sum & 1) << 7) + (sum >> 1) + *fileName83++;
return sum;
}
bool BmFF::VerifyMBR(void)
{
if(MBR_DISK_SERIAL_NUMBER(mRdMasterBootRecord) != BM_SERIAL_NUMBER && MBR_DISK_SERIAL_NUMBER(mRdMasterBootRecord) != BM_FACTORY_SERIAL_NUMBER)
{
printf("VerifyMBR()...Error: Disk serial number %u.\n", MBR_DISK_SERIAL_NUMBER(mRdMasterBootRecord));
return false;
}
return true;
}
bool BmFF::VerifyFATBS(void)
{
if(BS_TOTAL_SECTORS(mRdFat32BootSector) != (unsigned int)mPtTotalSectors)
{
printf("VerifyFATBS()...Error: total sector. readed = %u, expected = %u\n",
BS_TOTAL_SECTORS(mRdFat32BootSector), (unsigned int)mPtTotalSectors);
return false;
}
if(BS_SECTORS_PER_FAT(mRdFat32BootSector) != (unsigned int)mSectorsPerFat)
{
printf("VerifyFATBS()...Error: sector per fat. readed = %u, expected = %u\n",
BS_SECTORS_PER_FAT(mRdFat32BootSector), (unsigned int)mSectorsPerFat);
return false;
}
return true;
}
bool BmFF::VerifyFAT(void)
{
bool ret;
off_t fatStartSector = (off_t)(FIRST_SECTOR + FAT_RESERVED_SECTORS);
char *readFat0 = (char *)malloc(mSectorsPerFat * SECTOR_SIZE),
*readFat1 = (char *)malloc(mSectorsPerFat * SECTOR_SIZE);
int i, count;
unsigned int *rf, *wf;
ret = ReadSectors((char*)readFat0, fatStartSector, mSectorsPerFat);
if(ret == false) goto error;
ret = ReadSectors((char*)readFat1, fatStartSector + mSectorsPerFat, mSectorsPerFat);
if(ret == false) goto error;
count = mSectorsPerFat * SECTOR_SIZE / 4;
ret = true;
rf = (unsigned int *)readFat0;
wf = (unsigned int *)mMemFat;
for(i = 0; i < count; ++i)
{
// if(i <= 132)
// {
// if(i % 8 == 0)
// printf("\n");
// printf("(i=%03d,w=0x%08x,r=0x%08x) ", i, *wf, *rf);
// }
if(*wf != 0)
if(*wf != *rf)
{
printf("VerifyFAT0...i=%d, wf=0x%08x, rf=0x%08x\n", i, *wf, *rf);
ret = false;
break;
}
++wf;
++rf;
}
if(ret == true)
{
rf = (unsigned int *)readFat1;
wf = (unsigned int *)mMemFat;
for(i = 0; i < count; ++i)
{
if(*wf != 0)
if(*wf != *rf)
{
printf("VerifyFAT1...i=%d, wf=0x%08x, rf=0x%08x\n", i, *wf, *rf);
ret = false;
break;
}
++wf;
++rf;
}
}
free(readFat0);
free(readFat1);
if(ret == true)
printf("VerifyFAT OK.\n");
return ret;
error:
free(readFat0);
free(readFat1);
return false;
}
bool BmFF::VerifyDirectories(void)
{
bool ret;
int i, count;
unsigned int *rf, *wf;
char *readRootDirectory = (char *)malloc(mRootDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE),
*readLogDirectory = (char *)malloc(mLogDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE),
*readNormalDirectory = (char *)malloc(mNormalDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE),
*readEventDirectory = (char *)malloc(mEventDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE),
*readManualDirectory = (char *)malloc(mManualDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE),
*readParkingDirectory = (mParkingNormalPercent > 0) ? (char *)malloc(mParkingDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE) : NULL,
*readParkingNormalDirectory = (mParkingNormalPercent > 0) ? (char *)malloc(mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE) : NULL,
*readParkingEventDirectory = (mParkingEventPercent > 0) ? (char *)malloc(mParkingEventDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE) : NULL;
ret = ReadSectors(readRootDirectory, mRootDirectoryStartSector, mRootDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
ret = ReadSectors(readLogDirectory, mLogDirectoryStartSector, mLogDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
if(!mMstarPark)
if(mParkingNormalPercent > 0)
ret = ReadSectors(readParkingDirectory, mParkingDirectoryStartSector, mParkingDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
ret = ReadSectors(readNormalDirectory, mNormalDirectoryStartSector, mNormalDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
ret = ReadSectors(readEventDirectory, mEventDirectoryStartSector, mEventDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
if(mManualPercent > 0)
ret = ReadSectors(readManualDirectory, mManualDirectoryStartSector, mManualDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == true)
{
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
ret = ReadSectors(readParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
}
else
{
ret = ReadSectors(readParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
ret = ReadSectors(readParkingEventDirectory, mParkingEventDirectoryStartSector, mParkingEventDirectoryClusters * SECTORS_PER_CLUSTER);
}
}
}
if(ret == false) goto error;
count = mRootDirectoryClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE / 4;
ret = true;
// if(ret == true)
// ret = VerifyRootDirectory(readRootDirectory);
if(ret == true)
ret = VerifyLogDirectory(readLogDirectory);
if(ret == true)
if(!mMstarPark)
if(mParkingNormalPercent > 0)
ret = VerifyParkingDirectory(readParkingDirectory);
if(ret == true)
{
if(!mNoPrintFlag) printf("VerifyNormal. records=%d, front_file_size=%d, rear_file_size=%d\n",
mNormalRecords, mNormalFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mNormalRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readNormalDirectory, mNormalDirectoryClusters * CLUSTER_SIZE, (char*)".NORM", (char*)"NORM",
mNormalRecords, mNormalFrontFileClusters, mNormalRearFileClusters);
}
if(ret == true)
{
if(!mNoPrintFlag) printf("VerifyEvent. records=%d, front_file_size=%d, rear_file_size=%d\n",
mEventRecords, mEventFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mEventRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readEventDirectory, mEventDirectoryClusters * CLUSTER_SIZE, (char*)".EVEN", (char*)"EVEN",
mEventRecords, mEventFrontFileClusters, mEventRearFileClusters);
}
if(ret == true)
{
if(mManualPercent > 0)
{
if(!mNoPrintFlag) printf("VerifyManual. records=%d, front_file_size=%d, rear_file_size=%d\n",
mManualRecords, mManualFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mManualRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readManualDirectory, mManualDirectoryClusters * CLUSTER_SIZE, (char*)".MANU", (char*)"MANU",
mManualRecords, mManualFrontFileClusters, mManualRearFileClusters);
}
}
if(ret == true)
{
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
if(!mNoPrintFlag) printf("VerifyParking. records=%d, front_file_size=%d, rear_file_size=%d\n",
mParkingNormalRecords, mParkingFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mParkingRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readParkingNormalDirectory, mParkingNormalDirectoryClusters * CLUSTER_SIZE, (char*)".PARK", (char*)"PARK",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters);
}
else
{
if(!mNoPrintFlag) printf("VerifyParkingNormal. records=%d, front_file_size=%d, rear_file_size=%d\n",
mParkingNormalRecords, mParkingFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mParkingRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readParkingNormalDirectory, mParkingNormalDirectoryClusters * CLUSTER_SIZE, (char*)".PNOR", (char*)"PNOR",
mParkingNormalRecords, mParkingFrontFileClusters, mParkingRearFileClusters);
if(!mNoPrintFlag) printf("VerifyParkingEvent. records=%d, front_file_size=%d, rear_file_size=%d\n",
mParkingEventRecords, mParkingFrontFileClusters * SECTORS_PER_CLUSTER * SECTOR_SIZE,
mParkingRearFileClusters *SECTORS_PER_CLUSTER * SECTOR_SIZE);
ret = VerifyRecordDirectory(readParkingEventDirectory, mParkingEventDirectoryClusters * CLUSTER_SIZE, (char*)".PEVE", (char*)"PEVE",
mParkingEventRecords, mParkingFrontFileClusters, mParkingRearFileClusters);
}
}
}
free(readRootDirectory);
free(readLogDirectory);
free(readNormalDirectory);
free(readEventDirectory);
if(mManualPercent > 0)
free(readManualDirectory);
if(mParkingNormalPercent > 0)
{
free(readParkingDirectory);
free(readParkingNormalDirectory);
free(readParkingEventDirectory);
}
return ret;
error:
free(readRootDirectory);
free(readLogDirectory);
free(readNormalDirectory);
free(readEventDirectory);
if(mManualPercent > 0)
free(readManualDirectory);
if(mParkingNormalPercent > 0)
{
free(readParkingDirectory);
free(readParkingNormalDirectory);
free(readParkingEventDirectory);
}
return false;
}
bool BmFF::VerifyRootDirectory(char *buff)
{
bool ret = true;
unsigned char attribute;
char fn83[32];
int offsetByParking = (mParkingNormalPercent > 0) ? 0x20 : 0;
if(!mMstarPark)
if(mParkingNormalPercent > 0)
{
if(ret == true)
{
GetDirFileAttribute(buff + 0x00, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", PARKING_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + 0x00, fn83);
if(strcmp(fn83, PARKING_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", PARKING_DIRECTORY, fn83);
ret = false;
}
}
}
if(ret == true)
{
GetDirFileAttribute(buff + offsetByParking + 0x00, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", LOG_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + offsetByParking + 0x00, fn83);
if(strcmp(fn83, LOG_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", LOG_DIRECTORY, fn83);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + offsetByParking + 0x20, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", NORMAL_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + offsetByParking + 0x20, fn83);
if(strcmp(fn83, NORMAL_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", NORMAL_DIRECTORY, fn83);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + offsetByParking + 0x40, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", EVENT_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + offsetByParking + 0x40, fn83);
if(strcmp(fn83, EVENT_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", EVENT_DIRECTORY, fn83);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + offsetByParking + 0x60, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", MANUAL_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
if(mManualPercent > 0)
{
GetDirFileName(buff + offsetByParking + 0x60, fn83);
if(strcmp(fn83, MANUAL_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", MANUAL_DIRECTORY, fn83);
ret = false;
}
}
}
if(mMstarPark)
if(mParkingNormalPercent > 0)
{
if(ret == true)
{
GetDirFileAttribute(buff + offsetByParking + 0x80, attribute);
if(attribute != 0x10)
{
printf("VerifyRootDirectory error. %s_attr=0x%02x\n", PARKING_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + offsetByParking + 0x80, fn83);
if(strcmp(fn83, PARKING_DIRECTORY) != 0)
{
printf("VerifyRootDirectory error. %s_dirname=%s\n", PARKING_DIRECTORY, fn83);
ret = false;
}
}
}
if(ret)
printf("VerifyRootDirectory OK.\n");
return ret;
}
bool BmFF::VerifyLogDirectory(char *buff)
{
bool ret = true;
unsigned char attribute;
char fn83[32];
unsigned int fileSize;
// if(ret == true)
// {
// GetDirFileName(buff + 0x40, fn83);
// if(strcmp(fn83, LOG_SYSTEM1_FILE) != 0)
// {
// printf("VerifyLogDirectory error. %s_filename=%s\n", LOG_SYSTEM1_FILE, fn83);
// ret = false;
// }
// }
if(ret == true)
{
GetDirFileSize(buff + 0x40, fileSize);
if(fileSize != LOG0_FILE_SIZE)
{
printf("VerifyLogDirectory error. %s_fileSize=%d\n", LOG_SYSTEM0_FILE, fileSize);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + 0x40, attribute);
if(attribute != 0x20)
{
printf("VerifyLogDirectory error. %s_attr=0x%02x\n", LOG_SYSTEM0_FILE, attribute);
ret = false;
}
}
// if(ret == true)
// {
// GetDirFileName(buff + 0x60, fn83);
// if(strcmp(fn83, LOG_SYSTEM2_FILE) != 0)
// {
// printf("VerifyLogDirectory error. %s_filename=%s\n", LOG_SYSTEM2_FILE, fn83);
// ret = false;
// }
// }
if(ret == true)
{
GetDirFileSize(buff + 0x60, fileSize);
if(fileSize != LOG1_FILE_SIZE)
{
printf("VerifyLogDirectory error. %s_fileSize=%d\n", LOG_SYSTEM1_FILE, fileSize);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + 0x60, attribute);
if(attribute != 0x20)
{
printf("VerifyLogDirectory error. %s_attr=0x%02x\n", LOG_SYSTEM1_FILE, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileSize(buff + 0x80, fileSize);
if(fileSize != LOG2_FILE_SIZE)
{
printf("VerifyLogDirectory error. %s_fileSize=%d\n", LOG_SYSTEM2_FILE, fileSize);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + 0x80, attribute);
if(attribute != 0x20)
{
printf("VerifyLogDirectory error. %s_attr=0x%02x\n", LOG_SYSTEM2_FILE, attribute);
ret = false;
}
}
if(ret)
if(!mNoPrintFlag) printf("VerifyLogDirectory OK.\n");
return ret;
}
bool BmFF::VerifyParkingDirectory(char *buff)
{
bool ret = true;
unsigned char attribute;
char fn83[32];
unsigned int fileSize;
if(ret == true)
{
GetDirFileAttribute(buff + 0x40, attribute);
if(attribute != 0x10)
{
if(!mNoPrintFlag) printf("VerifyParkingDirectory error. %s_attr=0x%02x\n", PARKING_NORMAL_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + 0x40, fn83);
if(strcmp(fn83, PARKING_NORMAL_DIRECTORY) != 0)
{
if(!mNoPrintFlag) printf("VerifyParkingDirectory error. %s_dirname=%s\n", PARKING_NORMAL_DIRECTORY, fn83);
ret = false;
}
}
if(ret == true)
{
GetDirFileAttribute(buff + 0x60, attribute);
if(attribute != 0x10)
{
if(!mNoPrintFlag) printf("VerifyParkingDirectory error. %s_attr=0x%02x\n", PARKING_EVENT_DIRECTORY, attribute);
ret = false;
}
}
if(ret == true)
{
GetDirFileName(buff + 0x60, fn83);
if(strcmp(fn83, PARKING_EVENT_DIRECTORY) != 0)
{
if(!mNoPrintFlag) printf("VerifyParkingDirectory error. %s_dirname=%s\n", PARKING_EVENT_DIRECTORY, fn83);
ret = false;
}
}
if(ret)
if(!mNoPrintFlag) printf("VerifyParkingDirectory OK.\n");
return ret;
}
bool BmFF::VerifyRecordDirectory(char *buff, int buffSize, char *headNameHidden, char *headNameNormal, int nRecords, int frontFileClusters, int rearFileClusters)
{
int i;
bool ret = true;
unsigned char attribute;
char fn83[32];
char ffn[64];
unsigned int fileSize;
unsigned int frontFileSize = frontFileClusters * CLUSTER_SIZE;
unsigned int rearFileSize = rearFileClusters * CLUSTER_SIZE;
int fileNameLength;
int nHidden = strlen(headNameHidden),
nNormal = strlen(headNameNormal);
bool front = true;
buff += 0x40;
buffSize -= 0x40;
if(rearFileClusters > 0)
nRecords *= 2;
for(i = 0; i < nRecords; ++i)
{
while((buff[0] != 0x42) && (buffSize >= 0x60))
{
buff += 0x60;
buffSize -= 0x60;
}
if(buffSize < 0x60)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error. too many sequence code error.\n");
ret = false;
break;
}
if(ret == true)
{
GetDirFileAttributeLong(buff, attribute);
if(attribute != 0x20/* && attribute != 0x22*/)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error. %s_%d_attr=0x%02x\n", headNameNormal, i, attribute);
ret = false;
break;
}
}
if(ret == true)
{
GetDirFileNameLong(buff, fn83, ffn);
fileNameLength = strlen(ffn);
if(fileNameLength < 20)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error. %s_%d_filename=%s, len=%d\n", headNameNormal, i, ffn, fileNameLength);
ret = false;
break;
}
if(ffn[0] != '.')
// if(attribute == 0x20)
{
if(strncmp(ffn, headNameNormal, nNormal) != 0)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error(1). %s_%d_filename=%s\n", headNameNormal, i, ffn);
ret = false;
break;
}
if(strncmp(ffn + fileNameLength - 5, "W.MP4", 5) == 0)
{
front = true;
}
#if (MODEL_CONFIG == BV3000)
else if(strncmp(ffn + fileNameLength - 5, "I.MP4", 5) == 0)
#else
else if(strncmp(ffn + fileNameLength - 5, "R.MP4", 5) == 0)
#endif
{
front = false;
}
else
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error(2). %s_%d_filename=%s\n", headNameHidden, i, ffn);
ret = false;
break;
}
}
else // if(attribute == 0x22)
{
if(strncmp(ffn, headNameHidden, nHidden) != 0)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error(3). %s_%d_filename=%s\n", headNameHidden, i, ffn);
ret = false;
break;
}
if(strncmp(ffn + fileNameLength - 5, "W.TMP", 5) == 0)
{
front = true;
}
#if (MODEL_CONFIG == BV3000)
else if(strncmp(ffn + fileNameLength - 5, "I.TMP", 5) == 0)
#else
else if(strncmp(ffn + fileNameLength - 5, "R.TMP", 5) == 0)
#endif
{
front = false;
}
else
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error(4). %s_%d_filename=%s\n", headNameHidden, i, ffn);
ret = false;
break;
}
}
}
if(ret == true)
{
GetDirFileSizeLong(buff, fileSize);
if(front == true)
{
if(fileSize != frontFileSize)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error. %s_%dF_filesize=%d/%d\n", headNameNormal, i, fileSize, frontFileSize);
ret = false;
break;
}
}
else
{
if(fileSize != rearFileSize)
{
if(!mNoPrintFlag) printf("VerifyRecordDirectory error. %s_%dR_filesize=%d/%d\n", headNameNormal, i, fileSize, rearFileSize);
ret = false;
break;
}
}
}
buff += 0x60;
buffSize -= 0x60;
}
if(ret)
if(!mNoPrintFlag) printf("VerifyRecordDirectory_%s nFiles = %d OK.\n", headNameNormal, nRecords);
return ret;
}
bool BmFF::ReadSectors(char *data, unsigned int startSector, unsigned int sectors)
{
ssize_t readed;
loff_t offset;
loff_t start = (loff_t)startSector * SECTOR_SIZE;
unsigned int size = sectors * SECTOR_SIZE;
offset = lseek64(mFd, start, SEEK_SET);
if(offset != start)
{
printf("ReadSectors lseek error...start sector=%u, nsectors=%u\n", startSector, sectors);
return false;
}
readed = read(mFd, data, size);
if(readed != size)
{
printf("ReadSectors read error...start sector=%u, nsectors=%u\n", startSector, sectors);
return false;
}
// if(!mNoPrintFlag) printf("ReadSectors OK. start sector=%u, nsectors=%u\n", startSector, sectors);
return true;
}
void BmFF::ForceFlush(void)
{
#if !(_WIN32)
int result;
OpenDevice();
errno = 0;
result = ioctl(mFd, BLKFLSBUF);
if (result && errno)
{
printf("=========================================================================\n");
printf(" BmFF::ForceFlush() Cannot flush. errno=%d\n", errno);
printf(" error=%s\n", strerror(errno));
printf("=========================================================================\n");
}
else if (result)
{
printf("=========================================================================\n");
printf(" BmFF::ForceFlush() Flush returned. result=%d\n", result);
printf("=========================================================================\n");
}
else if (errno)
{
printf("=========================================================================\n");
printf(" BmFF::ForceFlush() Flush returned. zero, but with errno=%d\n", errno);
printf(" error=%s\n", strerror(errno));
printf("=========================================================================\n");
}
else
{
printf("=========================================================================\n");
printf(" BmFF::ForceFlush() OK\n");
printf("=========================================================================\n");
}
CloseDevice();
#endif // #if !(_WIN32)
}
bool BmFF::GetDirStartAndSectors(string fileName, int &startSector, int &nSectors, int &nFiles)
{
bool ret = false;
if((fileName.compare(0, 4, "NORM") == 0) || (fileName.compare(0, 4, ".NOR") == 0))
{
startSector = mNormalDirectoryStartSector;
nSectors = mNormalDirectoryClusters * SECTORS_PER_CLUSTER;
nFiles = mNormalFiles;
ret = true;
}
else if((fileName.compare(0, 4, "EVEN") == 0) || (fileName.compare(0, 4, ".EVE") == 0))
{
startSector = mEventDirectoryStartSector;
nSectors = mEventDirectoryClusters * SECTORS_PER_CLUSTER;
nFiles = mEventFiles;
ret = true;
}
else if((fileName.compare(0, 4, "MANU") == 0) || (fileName.compare(0, 4, ".MAN") == 0))
{
startSector = mManualDirectoryStartSector;
nSectors = mManualDirectoryClusters * SECTORS_PER_CLUSTER;
nFiles = mManualFiles;
ret = true;
}
else if((fileName.compare(0, 4, "PNOR") == 0) || (fileName.compare(0, 4, ".PNO") == 0))
{
startSector = mParkingNormalDirectoryStartSector;
nSectors = mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER;
nFiles = mParkingNormalFiles;
ret = true;
}
else if((fileName.compare(0, 4, "PEVE") == 0) || (fileName.compare(0, 4, ".PEV") == 0))
{
startSector = mParkingEventDirectoryStartSector;
nSectors = mParkingEventDirectoryClusters * SECTORS_PER_CLUSTER;
nFiles = mParkingEventFiles;
ret = true;
}
return ret;
}
#if 0
bool BmFF::RenameRecordFile(string srcFileName, string trgFileName)
{
int dirStartSector;
int dirSectorSize;
int nFiles;
char *dirBuff, *data;
int i;
bool ret = false;
if(GetDirStartAndSectors(srcFileName, dirStartSector, dirSectorSize, nFiles) == false)
{
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile error...src=%s\n", srcFileName.c_str());
printf("==================================================================\n");
return false;
}
dirBuff = (char*)malloc(dirSectorSize * SECTOR_SIZE);
if(dirBuff == NULL)
{
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile...malloc error...src=%s\n", srcFileName.c_str());
printf("==================================================================\n");
return false;
}
mFd = open(mDeviceName.c_str(), O_RDWR);
if(mFd < 0)
{
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile...OpenDevice error. src=%s\n", srcFileName.c_str());
printf("==================================================================\n");
free(dirBuff);
return false;
}
if(ReadSectors(dirBuff, dirStartSector, dirSectorSize) == false)
{
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile...ReadSectors error...src=%s\n", srcFileName.c_str());
printf("==================================================================\n");
free(dirBuff);
close(mFd);
return false;
}
data = dirBuff + 0x40;
for(i = 0; i < nFiles; ++i)
{
char fn83[16];
char fnLong[128];
GetDirFileNameLong(data, fn83, fnLong);
if(srcFileName.compare(0, srcFileName.length(), fnLong) == 0)
{
int writeStartSector = (0x40 + i * 0x60) / SECTOR_SIZE;
int writeEndSector = (0x40 + i * 0x60 + 0x60) / SECTOR_SIZE;
int writeSectors = writeEndSector - writeStartSector + 1;
SetDirFileNameLong(data, fn83, trgFileName.c_str());
if(WriteSectors(dirBuff + writeEndSector * SECTOR_SIZE, dirStartSector + writeStartSector, writeSectors) != 0)
{
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile...WriteSectors error...src=%s\n", srcFileName.c_str());
printf("==================================================================\n");
break;
}
ret = true;
printf("==================================================================\n");
printf(" BmFF::RenameRecordFile OK...%s->%s\n", srcFileName.c_str(), trgFileName.c_str());
printf("==================================================================\n");
break;
}
data += 0x60;
}
free(dirBuff);
close(mFd);
return ret;
}
#endif
void BmFF::ZeroBlocks(int startSector, int nSectors)
{
ssize_t written;
char *buff;
int i;
buff = (char *)malloc(SECTOR_SIZE);
memset(buff, 0, SECTOR_SIZE);
loff_t to = ((((loff_t)startSector)) * SECTOR_SIZE);
loff_t offset = lseek64(mFd, to, SEEK_SET);
printf("SEEK:%I64d ->%I64d \n", offset, to);
if(offset != to || offset < 0){
printf("==================================================================\n");
printf(" BmFF::ZeroBlocks() seek Failed offset:%ld!=%ld \n", offset, (startSector * SECTOR_SIZE));
printf("==================================================================\n");
free(buff);
return;
}
for(i = 0; i < nSectors; ++i)
{
//lseek64(mFd, (loff_t)((startSector + i) * SECTOR_SIZE), SEEK_SET);
written = write(mFd, buff, SECTOR_SIZE); // ,&mOV
if(written != SECTOR_SIZE)
{
printf("==================================================================\n");
printf(" BmFF::ZeroBlocks() Failed...sector_num=%d (start:%d+num:%d)written:%d %lld \n", startSector + i,startSector,nSectors, written, offset);
printf("==================================================================\n");
break;
}
}
free(buff);
}
string BmFF::ReadFileName(int cluster)
{
unsigned int start_sector = mRootDirectoryStartSector + (cluster - 2) * SECTORS_PER_CLUSTER;
char buff[SECTOR_SIZE];
bool ret;
string fname = "";
ret = ReadSectors(buff, start_sector, 1);
if(ret)
{
buff[36 + 56 - 1] = 0;
fname = buff + 36;
if(memcmp(buff + 28, "\0\0\0\100free", 8) != 0)
fname = "";
else if (fname.size() != 22)
fname = "";
else if(fname.find(".MP4") == string::npos)
fname = "";
}
return fname;
};
void BmFF::WriteFileName(string fname, int cluster)
{
unsigned int start_sector = mRootDirectoryStartSector + (cluster - 2) * SECTORS_PER_CLUSTER;
char buff[SECTOR_SIZE];
memset(buff, 0, SECTOR_SIZE);
memcpy(buff + 28, "\0\0\0\100free", 8);
memcpy(buff + 36, fname.c_str(), fname.size());
WriteSectors(buff, start_sector, 1);
};
int BmFF::RecoverDirectories(void)
{
int ret = 0;
off_t fatStartSector = (off_t)(FIRST_SECTOR + FAT_RESERVED_SECTORS);
memset(mMemFat, 0, mSectorsPerFat * SECTOR_SIZE);
mMemFat[0] = 0x0ffffff8;
mMemFat[1] = 0xffffffff;
mCurrentFatOffset = mRootDirectoryStartCluster;
MakeMemDirectories();
if(!mMstarPark)
if(mParkingNormalPercent > 0)
ret = WriteSectors(mMemParkingDirectory, mParkingDirectoryStartSector, mParkingDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemNormalDirectory, mNormalDirectoryStartSector, mNormalDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemEventDirectory, mEventDirectoryStartSector, mEventDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
ret = WriteSectors(mMemManualDirectory, mManualDirectoryStartSector, mManualDirectoryClusters * SECTORS_PER_CLUSTER);
if(ret == 0)
{
if(mParkingNormalPercent > 0)
{
if(mMstarPark)
{
ret = WriteSectors(mMemParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
}
else
{
ret = WriteSectors(mMemParkingNormalDirectory, mParkingNormalDirectoryStartSector, mParkingNormalDirectoryClusters * SECTORS_PER_CLUSTER);
ret = WriteSectors(mMemParkingEventDirectory, mParkingEventDirectoryStartSector, mParkingEventDirectoryClusters * SECTORS_PER_CLUSTER);
}
}
}
return ret;
}
#endif // #if (SUPPORT_FORMAT_FREE)