3181 lines
111 KiB
C++
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)
|
|
|