unsigned char ReadParameterName(unsigned int paramIndex, char* name) { Boot boot; ReadBootSector(&boot); ParamDescriptor paramDescriptor; ExtendedParamDescriptor extendedParamDescriptor; unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); if(descriptorAdr == 0xFFFF)//there are no parameter with such index return 0; ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); if(paramDescriptor.paramName[0] == 0x0F) { unsigned int extendedDescriptorCount = paramDescriptor.paramName[1] + (paramDescriptor.paramName[2]<<8); unsigned int i = 1; for(i; i < (extendedDescriptorCount + 1); i++) { ReadDescriptorByAddress(descriptorAdr + boot.DescriptorSize*i, &extendedParamDescriptor); int j=0; for(j;j<boot.DescriptorSize;j++) name[(i-1)*boot.DescriptorSize + j] = extendedParamDescriptor.paramName[j]; } } else { name[0] = 0; strcat(name,paramDescriptor.paramName); } return strlen(name); }
RETVAL CheckDescriptorInFat(RDWRHandle handle) { struct BootSectorStruct boot; SECTOR fatstart; char buffer[BYTESPERSECTOR], *p; if (!ReadBootSector(handle, &boot)) return ERROR; fatstart = GetFatStart(handle); if (!fatstart) return ERROR; if (ReadSectors(handle, 1, fatstart, buffer) == -1) return FALSE; if (boot.descriptor == buffer[0]) { return SUCCESS; } else { ReportFileSysError("Wrong descriptor value in FAT", 0, &p, 0, FALSE); } return FAILED; }
unsigned int FindMaxIndex() { Boot boot; ReadBootSector(&boot); unsigned int maxIndex = 0; ParamDescriptor descriptor; int adr = boot.BootSectorSize + boot.FatSectorSize; for(adr; adr < boot.BootSectorSize + boot.FatSectorSize + boot.DescriptorSectorSize; adr += boot.DescriptorSize) { ReadDescriptorByAddress(adr, &descriptor); if(descriptor.paramName[0] == 0) break; if(maxIndex < descriptor.index) maxIndex = descriptor.index; if(descriptor.paramName[0] == 0x0F)//extended { unsigned int extCount = descriptor.paramName[1] + (descriptor.paramName[2]<<8); adr+=extCount*boot.DescriptorSize; continue; } } if(maxIndex == 0) return 0x1FFF; return maxIndex; }
unsigned int FindDescriptorAdrByIndex(unsigned int index) { Boot boot; ReadBootSector(&boot); unsigned int descriptorAdr = 0xFFFF;//there are no descriptor with such index ParamDescriptor descriptor; int adr = boot.BootSectorSize + boot.FatSectorSize; for(adr; adr < boot.BootSectorSize + boot.FatSectorSize + boot.DescriptorSectorSize; adr += boot.DescriptorSize) { ReadDescriptorByAddress(adr, &descriptor); if(descriptor.index == index) { descriptorAdr = adr; break; } if(descriptor.paramName[0] == 0x0F)//extended { unsigned int extCount = descriptor.paramName[1] + (descriptor.paramName[2]<<8); adr+=extCount*boot.DescriptorSize; continue; } if(descriptor.paramName[0] == 0) break; } return descriptorAdr; }
RETVAL PlaceDescriptorInFat(RDWRHandle handle) { struct BootSectorStruct boot; SECTOR fatstart; char buffer[BYTESPERSECTOR], *p; if (!ReadBootSector(handle, &boot)) return ERROR; fatstart = GetFatStart(handle); if (!fatstart) return ERROR; if (ReadSectors(handle, 1, fatstart, buffer) == -1) return ERROR; if (buffer[0] != boot.descriptor) { ReportFileSysError("Wrong descriptor value in FAT", 0, &p, 0, FALSE); buffer[0] = boot.descriptor; if (WriteSectors(handle, 1, fatstart, buffer, WR_FAT) == -1) return ERROR; if (!BackupFat(handle)) return ERROR; } return SUCCESS; }
BOOL BackupBoot(RDWRHandle handle) { int fatlabelsize = GetFatLabelSize(handle); SECTOR BackupSector; struct BootSectorStruct* boot; BOOL retVal = TRUE; if (fatlabelsize == FAT32) { BackupSector = GetFAT32BackupBootSector(handle); if (!BackupSector) { RETURN_FTEERR(FALSE); } boot = AllocateBootSector(); if (!boot) RETURN_FTEERR(FALSE); if (!ReadBootSector(handle, boot) || (WriteSectors(handle, 1, BackupSector, (void*) boot, WR_UNKNOWN) == -1)) { RETURN_FTEERR(FALSE); } FreeBootSector(boot); } RETURN_FTEERR(retVal); }
RETVAL CorrectFSString(RDWRHandle handle) { char* correct; struct BootSectorStruct bootsect; switch (CheckFSString(handle)) { case SUCCESS: break; case FAILED: correct = GetCorrectFSString(handle); if (!correct) return ERROR; if (!ReadBootSector(handle, &bootsect)) return ERROR; correct = GetCorrectFSString(handle); WriteBPBFileSystemString(&bootsect, correct); if (!WriteBootSector(handle, &bootsect)) return ERROR; break; case FAIL: return ERROR; } return SUCCESS; }
int DescriptorCheck(RDWRHandle handle) { struct BootSectorStruct boot; if (!ReadBootSector(handle, &boot)) return FALSE; switch (boot.descriptor) { case 0xFE: return CheckKnownFormats(&boot, &ValuesFEh); case 0xFF: return CheckKnownFormats(&boot, &ValuesFFh); case 0xFC: return CheckKnownFormats(&boot, &ValuesFCh); case 0xFD: return CheckKnownFormats(&boot, &ValuesFDh); case 0xF9: if (!CheckKnownFormats(&boot, &ValuesF9ah)) return CheckKnownFormats(&boot, &ValuesF9bh); else return TRUE; case 0xF0: return CheckKnownFormats(&boot, &ValuesF0h); } return TRUE; }
char AddParameter(char* name, char type, char* data, unsigned int dataLength) { Boot boot; ReadBootSector(&boot); ParamDescriptor paramDescriptor; paramDescriptor.parameterType = type; paramDescriptor.index = FindMaxIndex()+1; double clustersCount = (double)dataLength/boot.ClusterSize; clustersCount = ceil(clustersCount); //fat (clusters sequence) unsigned int clusterNum = AllocateClustersSequence(clustersCount); if(clusterNum==0xFFFF) return 0; paramDescriptor.startCluster = clusterNum; //data area int i=0; for(i;i<clustersCount;i++) { WriteDataToCluster(clusterNum,data+i*boot.ClusterSize); clusterNum = ReadNextFat(clusterNum); } //find free descriptor adr unsigned int freeDescriptorAdr = FindFreeDescriptorAdr(); if(freeDescriptorAdr == 0xFFFF) return 0; //name + write descriptor if(strlen(name)<4)//simple descriptor { paramDescriptor.paramName[0] = 0; strcat(paramDescriptor.paramName,name); WriteDescriptorByAddress(freeDescriptorAdr,¶mDescriptor); return 1; } //extended descriptors paramDescriptor.paramName[0] = 0x0F;//exteded descripto sign //count extended descriptors num double buf = (double)(strlen(name) + 1)/boot.DescriptorSize; unsigned int extendedDescriptorsCount = (int)ceil(buf); char *ch = &extendedDescriptorsCount; paramDescriptor.paramName[1] = ch[0]; paramDescriptor.paramName[2] = ch[1]; paramDescriptor.paramName[3] = 0; WriteDescriptorByAddress(freeDescriptorAdr,¶mDescriptor); i=0; ExtendedParamDescriptor extendedDescriptor; for(i;i<extendedDescriptorsCount;i++) { freeDescriptorAdr += boot.DescriptorSize; int j=0; for(j;j<boot.DescriptorSize;j++) extendedDescriptor.paramName[j] = name[i*boot.DescriptorSize + j]; WriteDescriptorByAddress(freeDescriptorAdr,&extendedDescriptor); } return 1; }
char ReadParameterType(unsigned int paramIndex) { Boot boot; ReadBootSector(&boot); unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); if(descriptorAdr == 0xFFFF)//there are no descriptors with such index return -1; ParamDescriptor paramDescriptor; ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); return paramDescriptor.parameterType; }
char EditParameterName(unsigned int paramIndex, char* name) { Boot boot; ReadBootSector(&boot); char zero = 0; ParamDescriptor paramDescriptor; unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); //deleting of descriptors if(paramDescriptor.paramName[0] == 0x0F) { int extendedDescriptorCount = paramDescriptor.paramName[1] + paramDescriptor.paramName[2]<<8; int i = 1; for(i; i < (extendedDescriptorCount + 1); i++) { FramWrite(descriptorAdr + i*boot.DescriptorSize, &zero, sizeof(char)); } } FramWrite(descriptorAdr, &zero, sizeof(char)); DescriptorsDefragmentation(); unsigned int freeDescriptorAdr = FindFreeDescriptorAdr(); if(freeDescriptorAdr == 0xFFFF) return 0; //name + write descriptor if(strlen(name)<4)//simple descriptor { paramDescriptor.paramName[0] = 0; strcat(paramDescriptor.paramName,name); WriteDescriptorByAddress(freeDescriptorAdr,¶mDescriptor); return 1; } //extended descriptors paramDescriptor.paramName[0] = 0x0F;//exteded descripto sign //count extended descriptors num double buf = (double)(strlen(name) + 1)/boot.DescriptorSize; unsigned int extendedDescriptorsCount = (int)ceil(buf); char *ch = &extendedDescriptorsCount; paramDescriptor.paramName[1] = ch[0]; paramDescriptor.paramName[2] = ch[1]; paramDescriptor.paramName[3] = 0; WriteDescriptorByAddress(freeDescriptorAdr,¶mDescriptor); int ii=0; ExtendedParamDescriptor extendedDescriptor; for(ii;ii<extendedDescriptorsCount;ii++) { freeDescriptorAdr += boot.DescriptorSize; int j=0; for(j;j<boot.DescriptorSize;j++) extendedDescriptor.paramName[j] = name[ii*boot.DescriptorSize + j]; WriteDescriptorByAddress(freeDescriptorAdr,&extendedDescriptor); } return 1; }
void ReadBootSector(TFatBootSector& aBootSector) { TInt r = ReadBootSector(TheFs, CurrentDrive(), KBootSectorNum<<KDefaultSectorLog2, aBootSector); test_KErrNone(r); if(!aBootSector.IsValid()) { test.Printf(_L("Wrong bootsector! Dump:\n")); aBootSector.PrintDebugInfo(); test(0); } }
BOOL MultipleBootCheck(RDWRHandle handle) { BOOL retval; int fatlabelsize = GetFatLabelSize(handle); SECTOR BackupSector; struct BootSectorStruct* boot1, *boot2; if (fatlabelsize == FAT32) { BackupSector = GetFAT32BackupBootSector(handle); if (!BackupSector) { RETURN_FTEERR(FAIL); } boot1 = AllocateBootSector(); if (!boot1) RETURN_FTEERR(FAIL); boot2 = AllocateBootSector(); if (!boot2) { FreeBootSector(boot1); RETURN_FTEERR(FAIL); } if (!ReadBootSector(handle, boot1) == -1) { FreeBootSector(boot1); RETURN_FTEERR(FAIL); } if (!ReadSectors(handle, 1, BackupSector, (void*) boot2) == -1) { FreeBootSector(boot1); FreeBootSector(boot2); RETURN_FTEERR(FAIL); } retval = (memcmp(boot1, boot2, BYTESPERSECTOR) == 0); FreeBootSector(boot1); FreeBootSector(boot2); return retval; } RETURN_FTEERR((fatlabelsize) ? TRUE : FAIL); }
void EditParameterValue(unsigned int paramIndex, char* value, unsigned int dataLength) { Boot boot; ReadBootSector(&boot); ParamDescriptor paramDescriptor; unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); unsigned int currentCluster = paramDescriptor.startCluster; double clustersCount = (double)dataLength/boot.ClusterSize; clustersCount = ceil(clustersCount); int i = 0; for(i;i<clustersCount;i++) { WriteDataToCluster(currentCluster, value+i*boot.ClusterSize); currentCluster = ReadNextFat(currentCluster); } }
unsigned int ReadParameterValue(unsigned int paramIndex, char* data) { Boot boot; ReadBootSector(&boot); ParamDescriptor paramDescriptor; unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); if(descriptorAdr==0xFFFF)//there are no parameter with such index return 0; ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); unsigned int currentCluster = paramDescriptor.startCluster; int i = 0; while(1) { ReadDataFromCluster(currentCluster, data+i*boot.ClusterSize); currentCluster = ReadNextFat(currentCluster); if(currentCluster == 0xFFFF) break; i++; } return (i+1)*boot.ClusterSize; }
char DeleteParameter(unsigned int paramIndex) { char zero = 0; Boot boot; ReadBootSector(&boot); unsigned int descriptorAdr = FindDescriptorAdrByIndex(paramIndex); ParamDescriptor paramDescriptor; ReadDescriptorByAddress(descriptorAdr, ¶mDescriptor); //clear data ClearClustersSequence(paramDescriptor.startCluster); //clear head descriptor if(paramDescriptor.paramName[0] == 0x0F) { int extendedDescriptorCount = paramDescriptor.paramName[1] + paramDescriptor.paramName[2]<<8; int i = 1; for(i; i < (extendedDescriptorCount + 1); i++) { FramWrite(descriptorAdr + i*boot.DescriptorSize, &zero, sizeof(char)); } } FramWrite(descriptorAdr, &zero, sizeof(char)); DescriptorsDefragmentation(); }
void GetBootInfo() { QuickFormat(); ReadBootSector(gBootSector); }
/** Mount a Fat volume. @param aForceMount Flag to indicate whether mount should be forced to succeed if an error occurs @leave KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown. */ void CFatMountCB::MountL(TBool aForceMount) { const TInt driveNo = Drive().DriveNumber(); __PRINT3(_L("CFatMountCB::MountL() drv:%d, forceMount=%d, RuggedFAT:%d\n"), driveNo, aForceMount, IsRuggedFSys()); ASSERT(State() == ENotMounted || State() == EDismounted); SetState(EMounting); SetReadOnly(EFalse); User::LeaveIfError(CreateDrive(driveNo)); //-- read FAT configuration parameters from estart.txt iFatConfig.ReadConfig(driveNo); //-- initialise interface to the low-level drive access if(!iDriverInterface.Init(this)) User::LeaveIfError(KErrNoMemory); //-- get drive capabilities TLocalDriveCapsV2Buf capsBuf; User::LeaveIfError(LocalDrive()->Caps(capsBuf)); iSize=capsBuf().iSize; iRamDrive = EFalse; if(capsBuf().iMediaAtt & KMediaAttVariableSize) {//-- this is a RAM drive UserSvr::UnlockRamDrive(); iRamDrive = ETrue; } if(aForceMount) {//-- the state is "forcedly mounted", special case. This is an inconsistent state. SetState(EInit_Forced); return; } //-- read boot sector. If main is damaged, try to use backup one instead if this is not a RAM drive. TFatBootSector bootSector; User::LeaveIfError(ReadBootSector(bootSector, iRamDrive)); //-- print out boot sector debug information bootSector.PrintDebugInfo(); //-- determine FAT type by data from boot sector. This is done by counting number of clusters, not by BPB_RootEntCnt SetFatType(bootSector.FatType()); ASSERT(iFatType != EInvalid); //-- this shall be checked in ReadBootSector() if(bootSector.RootDirEntries() == 0 && !Is32BitFat()) {//-- FAT types mismatch. BPB_RootEntCnt is 0, which can be only for FAT32, but the number of clusters is less //-- than required for FAT32. Probably this is incorrectly FAT32 formatted media. Put the drive into ReadOnly mode, assuming //-- that is FAT32. __PRINT(_L("FAT type mismatch! Setting drive to ReadOnly mode for FAT32. \n")); SetFatType(EFat32); //-- force FAT type to be FAT32 SetReadOnly(ETrue); } //-- store volume UID, it can be checked on Remount iUniqueID = bootSector.UniqueID(); //-- populate volume parameters with the values from boot sector. They had been validated in TFatBootSector::IsValid() iVolParam.Populate(bootSector); //-- initialize the volume InitializeL(capsBuf()); ASSERT(State()==EInit_R); GetVolumeLabelFromDiskL(bootSector); __PRINT2(_L("CFatMountCB::MountL() Completed, drv: %d, state:%d"), DriveNumber(), State()); }