static BOOL RenameFile(RDWRHandle handle, struct DirectoryPosition* pos, struct DirectoryEntry* entry, CLUSTER firstcluster) { BOOL retval; int counter=0; for (;;) { retval = LoFileNameExists(handle, firstcluster, entry->filename, entry->extension); if (retval == FALSE) break; if (retval == FAIL) return FALSE; counter++; sprintf(entry->extension, "%03d", counter); if (IsCurrentDir(*entry)) { memcpy(entry->filename, "DOT ", 8); } if (IsPreviousDir(*entry)) { memcpy(entry->filename, "DOTDOT ", 8); } } return WriteDirectory(handle, pos, entry); }
STATIC BOOL SubdirGetter(RDWRHandle handle, struct DirectoryPosition* pos, void** buffer) { struct DirectoryEntry entry; struct Pipe** pipe = (struct Pipe**) buffer; handle = handle; if (!GetDirectory(handle, pos, &entry)) return FAIL; if (IsLFNEntry(&entry) || (IsDeletedLabel(entry)) || (IsCurrentDir(entry)) || (IsPreviousDir(entry))) { return TRUE; } if (entry.attribute & FA_DIREC) { if ((*pipe)->n == (*pipe)->counter) { memcpy((*pipe)->pos, pos, sizeof(struct DirectoryPosition)); return FALSE; } (*pipe)->counter++; } 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); }
void MemorySortEntries(struct DirectoryEntry* entries, int amofentries) { int i=0, realentries = 0; struct DirectoryEntry* temp = entries; SetResourceConfiguration(&MemConfig); if (amofentries == 0) return; if (IsCurrentDir(entries[0])) { if (amofentries == 1) return; entries++; i++; } if (IsPreviousDir(entries[0])) { entries++; i++; } for (; i < amofentries; i++) if (IsLFNEntry(&temp[i]) == 0) realentries++; if (realentries) SelectionSortEntries(entries, realentries); }
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; }
BOOL GetNthSubDirectoryPosition(RDWRHandle handle, CLUSTER cluster, unsigned long n, struct DirectoryPosition* result) { int counter = 0; struct DirectoryPosition pos; struct DirectoryEntry* entry; entry = AllocateDirectoryEntry(); if (!entry) return FALSE; n++; /* n is 0 based */ while (n) { pos.sector = 0; pos.offset = 0; if (!GetNthDirectoryPosition(handle, cluster, counter++, &pos)) { FreeDirectoryEntry(entry); return FALSE; } if ((pos.sector == 0) && (pos.offset == 0)) /* Not found*/ { FreeDirectoryEntry(entry); return TRUE; } if (!GetDirectory(handle, &pos, entry)) { FreeDirectoryEntry(entry); return TRUE; } if (!IsLFNEntry((entry)) && (entry->attribute & FA_DIREC) && (!IsDeletedLabel(*entry)) && (!IsCurrentDir(*entry)) && (!IsPreviousDir(*entry))) { n--; } } memcpy(result, &pos, sizeof(struct DirectoryPosition)); 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 CheckEntryForInvalidChars(RDWRHandle handle, struct DirectoryPosition* pos, struct DirectoryEntry* direct, char* filename, BOOL fixit) { int i; BOOL invalidname = FALSE; BOOL InRoot; struct DirectoryEntry entry; memcpy(&entry, direct, sizeof(struct DirectoryEntry)); if (((entry.attribute & FA_LABEL) == 0) && /* Not checking volume labels */ !IsDeletedLabel(entry)) { if (IsPreviousDir(entry) || /* .. */ IsCurrentDir(entry)) /* . */ { /* See wether the given directory entry is in the root directory */ InRoot = IsRootDirPosition(handle, pos); if (InRoot == FAIL) return FAIL; /* All the '.' and '..' entries must be directories */ if (((entry.attribute & FA_DIREC) == 0) || (InRoot)) { if (IsCurrentDir(entry)) { if (InRoot) { ShowFileNameViolation(handle, "", "The root directory contains an '.' entry"); } else { ShowParentViolation(handle, filename, "%s contains an '.' entry that is not a directory"); } memcpy(entry.filename, "DOT ", 8); } else { if (InRoot) { ShowFileNameViolation(handle, "", "The root directory contains an '..' entry"); } else { ShowParentViolation(handle, filename, "%s contains an '..' entry that is not a directory"); } memcpy(entry.filename, "DOTDOT ", 8); } if (fixit) { memcpy(entry.extension, " ", 3); if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */ return FAIL; } return FALSE; } /* Check wether you realy have '.' and '..' */ if (IsCurrentDir(entry)) { if ((memcmp(entry.filename, ". ", 8) != 0) || (memcmp(entry.extension, " ", 3) != 0)) { ShowFileNameViolation(handle, filename, "%s contains invalid char(s)"); if (fixit) { memcpy(entry.filename, ". ", 8); memcpy(entry.extension, " ", 3); if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */ return FAIL; } } } if (IsPreviousDir(entry)) { if ((memcmp(entry.filename, ".. ", 8) != 0) || (memcmp(entry.extension, " ", 3) != 0)) { ShowFileNameViolation(handle, filename, "%s contains invalid char(s)"); if (fixit) { memcpy(entry.filename, ".. ", 8); memcpy(entry.extension, " ", 3); if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */ return FAIL; } } } } else { if (entry.filename[0] == ' ') { invalidname = TRUE; entry.filename[0] = 'A'; } /* file name */ for (i = 0; i < 8; i++) { if ((strchr(INVALIDSFNCHARS, entry.filename[i])) || (((unsigned char)(entry.filename[i]) < 0x20) && (entry.filename[i] != 0x05)) || (islower(entry.filename[i]))) { entry.filename[i] = 'A'; invalidname = TRUE; } } /* extension */ for (i = 0; i < 3; i++) { if ((strchr(INVALIDSFNCHARS, entry.extension[i])) || (((unsigned char)(entry.extension[i]) < 0x20) && (entry.extension[i] != 0x05)) || (islower(entry.extension[i]))) { entry.extension[i] = 'A'; invalidname = TRUE; } } if (invalidname) { ShowFileNameViolation(handle, filename, "%s contains invalid char(s)"); if (fixit) { if (!RenameFile(handle, pos, &entry, DirCluster)) /* Write the changes to disk */ return FAIL; } return FALSE; } } } return TRUE; }
static BOOL FilesSummaryGetter(RDWRHandle handle, struct DirectoryPosition* position, struct DirectoryEntry* entry, void** structure) { CLUSTER firstcluster; struct FilesSummary** info = (struct FilesSummary**) structure; unsigned long dirsize=0, *pdirsize = &dirsize, bytespercluster, labelsinfat; position = position; bytespercluster = GetSectorsPerCluster(handle) * BYTESPERSECTOR; if (!bytespercluster) return FAIL; if (entry->attribute & FA_LABEL) return TRUE; if (IsLFNEntry(entry)) return TRUE; if (IsDeletedLabel(*entry)) return TRUE; if (entry->attribute & FA_DIREC) { if (IsCurrentDir(*entry)) return TRUE; if (IsPreviousDir(*entry)) return TRUE; (*info)->DirectoryCount++; labelsinfat = GetLabelsInFat(handle); if (!labelsinfat) return FAIL; fatmap = CreateBitField(labelsinfat); if (!fatmap) return FAIL; firstcluster = GetFirstCluster(entry); if (!TraverseSubdir(handle, firstcluster, DirSizeGetter, (void**) &pdirsize, FALSE)) { return FAIL; } DestroyBitfield(fatmap); AddUlongLong(&(*info)->SizeOfDirectories[0],dirsize); return TRUE; /* Not taking directories into account when gathering information on files. */ } (*info)->TotalFileCount++; AddUlongLong(&(*info)->TotalSizeofFiles[0],entry->filesize); AddUlongLong(&(*info)->SizeOfAllFiles[0], CalculateClustersSize(entry->filesize, bytespercluster)); if (entry->attribute & FA_SYSTEM) { (*info)->SystemFileCount++; AddUlongLong(&(*info)->SizeOfSystemFiles[0], CalculateClustersSize(entry->filesize, bytespercluster)); } if (entry->attribute & FA_HIDDEN) { (*info)->HiddenFileCount++; AddUlongLong(&(*info)->SizeOfHiddenFiles[0], CalculateClustersSize(entry->filesize, bytespercluster)); } return TRUE; }