BOOL PerformRootDirChecks(RDWRHandle handle, BOOL fixit) { int fatlabelsize; struct Pipe pipe, *ppipe = &pipe; fatlabelsize = GetFatLabelSize(handle); switch (fatlabelsize) { case FAT12: case FAT16: pipe.fixit = fixit; pipe.result = TRUE; InitClusterEntryChecking(handle, 0, "The root directory"); switch (PreProcessClusterEntryChecking(handle, 0, "The root directory", fixit)) { case FALSE: pipe.result = FALSE; break; case FAIL: DestroyClusterEntryChecking(handle, 0, "The root directory"); return FAIL; } if (!TraverseRootDir(handle, RootDirChecker, (void**) &ppipe, TRUE)) { DestroyClusterEntryChecking(handle, 0, "The root directory"); return FAIL; } switch (PostProcessClusterEntryChecking(handle, 0, "The root directory", fixit)) { case FALSE: pipe.result = FALSE; break; case FAIL: pipe.result = FAIL; } DestroyClusterEntryChecking(handle, 0, "The root directory"); return pipe.result; case FAT32: return ScanFileChain(handle, 0, (struct DirectoryPosition*) NULL, (struct DirectoryEntry*) NULL, "\\", fixit); default: return FAIL; } }
BOOL GetRootDirVolumeLabel(RDWRHandle handle, struct DirectoryPosition* volumepos) { struct Pipe pipe, *ppipe = &pipe; pipe.found = FALSE; pipe.pos = volumepos; if (!TraverseRootDir(handle, VolumeGetter, (void**) &ppipe, TRUE)) return FAIL; return pipe.found; }
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; } }
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 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; }