long low_dircount(RDWRHandle handle, CLUSTER cluster, char attribute) { int fatlabelsize; struct PipeStruct pipe, *ppipe = &pipe; if (cluster == 0) { fatlabelsize = GetFatLabelSize(handle); switch (fatlabelsize) { case FAT12: case FAT16: return CountEntriesInRootDirectory(handle, attribute); case FAT32: cluster = GetFAT32RootCluster(handle); if (cluster) break; else return FAIL; default: return FAIL; } } pipe.count = 0; pipe.attribute = attribute; if (!TraverseSubdir(handle, cluster, counter, (void**) &ppipe, TRUE)) return FAIL; return pipe.count; }
BOOL GetNthDirectoryPosition(RDWRHandle handle, CLUSTER cluster, unsigned long n, struct DirectoryPosition* result) { int fatlabelsize; struct Pipe pipe, *ppipe = &pipe; pipe.n = n; pipe.counter = 0; pipe.pos = result; if (cluster == 0) { fatlabelsize = GetFatLabelSize(handle); switch (fatlabelsize) { case FAT12: case FAT16: { BOOL retVal; struct DirectoryPosition pos; struct DirectoryEntry* entry; retVal = GetRootDirPosition(handle, (unsigned short) n, &pos); if (retVal) { entry = AllocateDirectoryEntry(); if (!entry) return FALSE; if (!GetDirectory(handle, &pos, entry)) { FreeDirectoryEntry(entry); return FALSE; } if (entry->filename[0] != LASTLABEL) { memcpy(result, &pos, sizeof(struct DirectoryPosition)); } FreeDirectoryEntry(entry); } return retVal; } case FAT32: cluster = GetFAT32RootCluster(handle); if (cluster) break; else return FALSE; default: return FALSE; } } return TraverseSubdir(handle, cluster, positiongetter, (void**) &ppipe, TRUE); }
BOOL RemoveInvalidLFNs(RDWRHandle handle, CLUSTER firstcluster, struct DirectoryPosition* pos1, struct DirectoryPosition* pos2) { struct RemovePipe pipe, *ppipe = &pipe; pipe.begin = pos1; pipe.end = pos2; return TraverseSubdir(handle, firstcluster, LFNRemover, (void**) &ppipe, TRUE); }
BOOL GetNthSubDirectoryPosition(RDWRHandle handle, CLUSTER cluster, unsigned long n, struct DirectoryPosition* result) { struct Pipe pipe, *ppipe = &pipe; pipe.n = n; pipe.counter = 0; pipe.pos = result; return TraverseSubdir(handle, cluster, SubdirGetter, (void**) &ppipe, TRUE); }
BOOL LoFileNameExists(RDWRHandle handle, CLUSTER firstcluster, char* filename, char* extension) { struct Pipe pipe, *ppipe = &pipe; pipe.filename = filename; pipe.extension = extension; pipe.exists = FALSE; if (!TraverseSubdir(handle, firstcluster, ExistanceChecker, (void**) &ppipe, TRUE)) RETURN_FTEERROR(FAIL); return pipe.exists; }
int SearchDirectory(RDWRHandle handle, char* dir, CLUSTER* fatcluster, struct DirectoryPosition* pos, int func(RDWRHandle handle, struct DirectoryPosition* pos, struct DirectoryEntry* entry)) { int i, j; struct PipeStruct pipe, *ppipe = &pipe; char filename[8], extension[3]; pipe.found = FALSE; pipe.filename = filename; pipe.extension = extension; pipe.error = FALSE; pipe.func = func; memset(filename, ' ', 8); for (i = 0; i < 8; i++) if ((dir[i] == '.') || (dir[i] == '\0')) break; else filename[i] = dir[i]; memset(extension, ' ', 3); for (j = 0; j < 3; j++) if (dir[i+j] == '.') continue; else if (dir[i+j] == '\0') break; else extension[j] = dir[i]; if (IsRootDirPosition(handle, pos)) { if (!TraverseRootDir(handle, DirSearcher, (void**) &ppipe, TRUE)) return FALSE; return pipe.found; } else { if (!TraverseSubdir(handle, *fatcluster, DirSearcher, (void**) &ppipe, TRUE)) return FALSE; return pipe.found; } }
static int getentry(RDWRHandle handle, CLUSTER cluster, int slotorentry, unsigned entry, unsigned slot, struct DirectoryEntry* result) { struct Pipe pipe, *ppipe = &pipe; pipe.slotorentry = slotorentry; pipe.entrynr = entry; pipe.slot = slot; pipe.ecounter = 0; pipe.scounter = 0; pipe.entry = result; return TraverseSubdir(handle, cluster, entrygetter, (void**) &ppipe, TRUE); }
BOOL WalkDirectoryTree(RDWRHandle handle, int (*func) (RDWRHandle handle, struct DirectoryPosition* position, void** structure), void** structure) { int top = 0; struct StackElement* stack; CLUSTER cluster = 0, temp; unsigned long current = 0; struct DirectoryPosition pos; struct DirectoryEntry* entry; struct StackElement element; struct PipeStruct pipe, *ppipe = &pipe; pipe.func = func; pipe.structure = structure; pipe.stop = FALSE; if (!TraverseRootDir(handle, ActionWalker, (void**)&ppipe, TRUE)) return FALSE; if (pipe.stop) return TRUE; stack = (struct StackElement*)FTEAlloc(DIR_STACK_DEPTH * sizeof(struct StackElement)); if (!stack) return FALSE; for (;;) { /* If there still are sub directories in this directory, push the cluster of that directory. */ pos.sector = 0; pos.offset = 0; if (!GetNthSubDirectoryPosition(handle, cluster, current, &pos)) { FTEFree(stack); return FALSE; } if ((pos.sector != 0) || (pos.offset != 0)) { entry = AllocateDirectoryEntry(); if (!entry) { FTEFree(stack); return FALSE; } if (top < DIR_STACK_DEPTH) { element.cluster = cluster; element.index = current; PushDirectoryEntry(stack, &top, &element); } else { FreeDirectoryEntry(entry); /* Directory level to deep!? */ FTEFree(stack); return FALSE; } if (!GetDirectory(handle, &pos, entry)) { FreeDirectoryEntry(entry); FTEFree(stack); return FALSE; } /* Descend in the directory tree and call the function for every directory entry in that directory. */ temp = GetFirstCluster(entry); /* Don't descend in any directory that is invalid. */ if (temp && FAT_NORMAL(temp) && IsLabelValid(handle, temp)) { current = 0; cluster = temp; if (!TraverseSubdir(handle, cluster, ActionWalker, (void**) &ppipe, TRUE)) { FreeDirectoryEntry(entry); FTEFree(stack); return FALSE; } if (pipe.stop) { FreeDirectoryEntry(entry); FTEFree(stack); return TRUE; } } else /* cluster not valid, leave this directory */ { if (top-1 > 0) /* Be carefull when there are no sub directories in the volume. */ { PopDirectoryEntry(stack, &top, &element); PopDirectoryEntry(stack, &top, &element); current = element.index+1; /* Then find the next sub directory. */ cluster = element.cluster; } else { FreeDirectoryEntry(entry); break; } } FreeDirectoryEntry(entry); } /* If there are no more sub directories in the current directory, pop the current directory from the stack. */ else { if (top) /* Be carefull when there are no sub directories in the volume. */ { PopDirectoryEntry(stack, &top, &element); current = element.index+1; /* Then find the next sub directory. */ cluster = element.cluster; } else { break; } } } FTEFree(stack); 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; }