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); }
BOOL ReadDirEntry(RDWRHandle handle, unsigned short index, struct DirectoryEntry* entry) { struct DirectoryEntry* buf; SECTOR dirstart; /* We are using a sector as an array of directory entries. */ buf = (struct DirectoryEntry*)AllocateSector(handle); if (buf == NULL) RETURN_FTEERR(FALSE); dirstart = GetDirectoryStart(handle); if (!dirstart) RETURN_FTEERR(FALSE); if (ReadSectors(handle, 1, dirstart + (index / ENTRIESPERSECTOR), buf) == -1) { FreeSectors((SECTOR*)buf); RETURN_FTEERR(FALSE); } memcpy(entry, buf + (index % ENTRIESPERSECTOR), sizeof(struct DirectoryEntry)); FreeSectors((SECTOR*)buf); return TRUE; }
CLUSTER LocatePreviousDir(RDWRHandle handle, CLUSTER firstdircluster) { SECTOR* sectbuf; SECTOR sector; assert(firstdircluster); sectbuf = AllocateSector(handle); if (!sectbuf) RETURN_FTEERR(0xFFFFFFFFL); sector = ConvertToDataSector(handle, firstdircluster); if (!sector) { FreeSectors(sectbuf); RETURN_FTEERR(0xFFFFFFFFL); } if (!ReadDataSectors(handle, 1, sector, (void*) sectbuf)) { FreeSectors(sectbuf); RETURN_FTEERR(0xFFFFFFFFL); } if (IsPreviousDir(((struct DirectoryEntry*) sectbuf)[1])) { CLUSTER retVal = GetFirstCluster(&(((struct DirectoryEntry*) sectbuf)[1])); FreeSectors(sectbuf); return retVal; } SetFTEerror(FTE_FILESYSTEM_BAD); FreeSectors(sectbuf); RETURN_FTEERR(0xFFFFFFFFL); }
BOOL DiskSortEntries(RDWRHandle handle, CLUSTER cluster) { int i=0; long totalcount, lfncount, realcount; struct DiskEntryGetterStruct parameters; struct DirectoryPosition pos; struct DirectoryEntry entry; parameters.handle = handle; parameters.cluster = cluster; SetResourceConfiguration(&DiskConfig); totalcount = low_dircount(handle, cluster, 0xffff); if (totalcount == -1) RETURN_FTEERR(FALSE); lfncount = low_dircount(handle, cluster, LFN_ATTRIBUTES); if (lfncount == -1) RETURN_FTEERR(FALSE); realcount = totalcount - lfncount; for (i = 0; i < 2; i++) { if (!GetNthDirectoryPosition(handle, cluster, i, &pos)) { RETURN_FTEERR(FALSE); } if (!GetDirectory(handle, &pos, &entry)) { RETURN_FTEERR(FALSE); } switch (i) { case 0: if (IsCurrentDir(entry)) { realcount--; } break; case 1: if (IsPreviousDir(entry)) { realcount--; } } } if (realcount && realcount <= INT_MAX) SelectionSortEntries(¶meters, (int)realcount); return TRUE; }
/* Notice that this assumes that the number of clusters is even. TODO: fix this. */ int MultipleFatCheck(RDWRHandle handle) { unsigned short sectorsperfat = GetSectorsPerFat(handle); unsigned char numberoffats = GetNumberOfFats(handle); unsigned long bytesinfat = GetBytesInFat(handle), compared = 0, rest; SECTOR fat1start = GetFatStart(handle), fat2start = fat1start, i, j; char buffer1[BYTESPERSECTOR]; char buffer2[BYTESPERSECTOR]; if ((sectorsperfat == 0) || (numberoffats == 0) || (fat1start == 0) || (bytesinfat == 0)) RETURN_FTEERR(FALSE); /* Not succeeded. */ if (numberoffats == 1) return TRUE; /* Succeeded when only one fat? */ rest = bytesinfat % BYTESPERSECTOR; for (i = 0; i < numberoffats - 1; i++) { fat2start += sectorsperfat; for (j = 0; j < sectorsperfat; j++) { ReadSectors(handle, 1, fat1start + j, buffer1); ReadSectors(handle, 1, fat2start + j, buffer2); if (compared == bytesinfat - rest) { if (memcmp(buffer1, buffer2, (int) rest) != 0) RETURN_FTEERR(FALSE); compared = 0; } else { if (memcmp(buffer1, buffer2, BYTESPERSECTOR) != 0) RETURN_FTEERR(FALSE); compared += BYTESPERSECTOR; } } } return TRUE; }
static BOOL VolumeGetter(RDWRHandle handle, struct DirectoryPosition* pos, void** structure) { struct Pipe *pipe = *((struct Pipe**) structure); struct DirectoryEntry* entry; assert (pos->sector && (pos->offset < 16)); entry = AllocateDirectoryEntry(); if (!entry) RETURN_FTEERR(FAIL); if (!GetDirectory(handle, pos, entry)) { FreeDirectoryEntry(entry); RETURN_FTEERR(FAIL); } if (IsLFNEntry(entry)) { FreeDirectoryEntry(entry); return TRUE; } if (IsDeletedLabel(*entry)) { FreeDirectoryEntry(entry); return TRUE; } if (entry->attribute & FA_LABEL) { pipe->found = TRUE; memcpy(pipe->pos, pos, sizeof(struct DirectoryPosition)); FreeDirectoryEntry(entry); RETURN_FTEERR(FALSE); } FreeDirectoryEntry(entry); return TRUE; }
static int entrygetter (RDWRHandle handle, struct DirectoryPosition* pos, void** buffer) { struct Pipe** pipe = (struct Pipe**) buffer; struct DirectoryEntry entry; if (!GetDirectory(handle, pos, &entry)) { RETURN_FTEERR(FAIL); } if (IsCurrentDir(entry) || IsPreviousDir(entry)) { return TRUE; } if ((*pipe)->entrynr == (*pipe)->ecounter) { if ((*pipe)->slotorentry == ENTRY) { memcpy((*pipe)->entry, &entry, sizeof(struct DirectoryEntry)); RETURN_FTEERR(FALSE); } else { if ((*pipe)->slot == (*pipe)->scounter) { memcpy((*pipe)->entry, &entry, sizeof(struct DirectoryEntry)); RETURN_FTEERR(FALSE); } (*pipe)->scounter++; return TRUE; } } if ((entry.attribute & FA_LABEL) == 0) (*pipe)->ecounter++; return TRUE; }
BOOL GetRootDirPosition(RDWRHandle handle, unsigned short index, struct DirectoryPosition* pos) { SECTOR dirstart = GetDirectoryStart(handle); if (!dirstart) RETURN_FTEERR(FALSE); pos->sector = dirstart + (index / ENTRIESPERSECTOR); pos->offset = index % ENTRIESPERSECTOR; return TRUE; }
SECTOR GetDirectoryStart(RDWRHandle handle) { unsigned short reserved; unsigned char fats; unsigned long SectorsPerFat; if (handle->dirbegin == 0) { reserved = GetReservedSectors(handle); if (reserved == 0) RETURN_FTEERR(FALSE); fats = GetNumberOfFats(handle); if (fats == 0) RETURN_FTEERR(FALSE); SectorsPerFat = GetSectorsPerFat(handle); if (SectorsPerFat == 0) RETURN_FTEERR(FALSE); handle->dirbegin = (SECTOR) reserved + ((SECTOR)fats * SectorsPerFat); } return handle->dirbegin; }
BOOL WriteDirEntry(RDWRHandle handle, unsigned short index, struct DirectoryEntry* entry) { int WriteDirectory(RDWRHandle handle, struct DirectoryPosition* pos, struct DirectoryEntry* direct); struct DirectoryPosition pos; if (!GetRootDirPosition(handle, index, &pos)) RETURN_FTEERR(FALSE); return WriteDirectory(handle, &pos, entry); }
BOOL GetRootDirVolumeLabel(RDWRHandle handle, struct DirectoryPosition* volumepos) { struct Pipe pipe, *ppipe = &pipe; assert(volumepos); pipe.found = FALSE; pipe.pos = volumepos; if (!TraverseRootDir(handle, VolumeGetter, (void**) &ppipe, TRUE)) RETURN_FTEERR(FAIL); assert(!pipe.found || (volumepos->sector && volumepos->offset < 16)); return pipe.found; }
BOOL IsRootDirPosition(RDWRHandle handle, struct DirectoryPosition* pos) { struct DirectoryPosition pos1; unsigned short NumberOfRootEntries; assert(pos->sector && (pos->offset < 16)); NumberOfRootEntries = GetNumberOfRootEntries(handle); if (NumberOfRootEntries == 0) return FALSE; /* Strange, but ultimately correct */ if (!GetRootDirPosition(handle, NumberOfRootEntries-1, &pos1)) RETURN_FTEERR(-1); if (pos->sector < pos1.sector) return TRUE; return ((pos->sector == pos1.sector) && (pos->offset <= pos1.offset)); }
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); }
int func5() { RETURN_FTEERR(5); }
int func4() { RETURN_FTEERR(4); }
int func3() { RETURN_FTEERR(3); }
int func2() { RETURN_FTEERR(2); }
int func1() { RETURN_FTEERR(1); }