/* * follow dir recursively scans through the file hierarchy * we check for consistency for every directory entry * taken from dos with some modifications. */ void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { append_clusters(cluster); struct direntry *dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); char buffer[MAXFILENAME]; int i = 0; for ( ; i < numDirEntries; i++) { append_clusters(cluster); uint16_t followclust = get_dirent(dirent, buffer); chkerr(dirent, buffer, image_buf, bpb); if (followclust) { follow_dir(followclust, indent+1, image_buf, bpb); } dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
/* * traverse root - taken from dos files. modified collectively * recursively follows directories from the root checking each file * for consistency as it goes */ void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry* dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); char buffer [MAXFILENAME]; //buffer for storing file names int i; for (i = 0; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = get_dirent(dirent, buffer); // deal with normal files if (dirent->deAttributes == ATTR_NORMAL) { chkerr(dirent, buffer, image_buf, bpb); } append_clusters(followclust); // append file cluster if (is_valid_cluster(followclust, bpb)) { append_clusters(followclust); follow_dir(followclust, 1, image_buf, bpb); } dirent++; } }
void checkandfix(uint8_t *image_buf, struct bpb33* bpb, int *refcount) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { //to print directory use print_dirent (change to get_dirent when done) uint16_t followclust = print_dirent(dirent, 0, image_buf, bpb, refcount); //char buffer[MAXFILENAME]; //uint16_t followclust = get_dirent(dirent, buffer); if (is_valid_cluster(followclust, bpb)) { refcount[followclust]++; //updating refcount for index of current cluster printf("refcount is: %d, followclust is: %d\n\n", refcount[followclust], followclust); follow_dir(followclust, 1, image_buf, bpb, refcount); } //this is where the magic happens...or in print_dirent? I'd rather do // it here dirent++; } }
/************FOLLOW_DIR***************/ void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb, int* refcount) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); //can't we just use int numDirEntries = bpb->RootDirEnts?? int i = 0; for ( ; i < numDirEntries; i++) { // char buffer[MAXFILENAME]; // uint16_t followclust = get_dirent(dirent, buffer); uint16_t followclust = print_dirent(dirent, indent, image_buf, bpb, refcount); //changed to print as follow_dir is called if (followclust) { refcount[followclust]++; follow_dir(followclust, indent+1, image_buf, bpb, refcount); } dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
void follow_dir(char* filename, uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); for ( int i=0; i < numDirEntries; i++) { uint16_t followclust = print_dirent(filename, dirent, indent); int count = -1; if (followclust!= 0) { count=compare(filename, followclust,dirent,image_buf,bpb); } else { } //printf("count: %i\n", count); if (followclust !=0) follow_dir(filename, followclust, indent+1, image_buf, bpb); dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
/***********SAVE_ORPHANS***************/ void orphan_search(uint8_t *image_buf, struct bpb33* bpb, int * refcount, int FATsz) { int count = 0; //count orphans int i = 2; for(; i < FATsz; i++) { uint16_t cluster = get_fat_entry(i, image_buf, bpb); if(cluster != (FAT12_MASK & CLUST_FREE) && cluster != (FAT12_MASK & CLUST_BAD) && refcount[i] == 0) { printf("FOUND AN ORPHAN, CLUSTER # = %d\n", i); count++; int orphan_size = 1; refcount[i] = 1; uint16_t orphan_cluster = cluster; while(is_valid_cluster(orphan_cluster, bpb)) { if (refcount[orphan_cluster] == 1) { set_fat_entry(orphan_cluster, (FAT12_MASK & CLUST_EOFS), image_buf, bpb); } else if(refcount[orphan_cluster] > 1) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); dirent->deName[0] = SLOT_DELETED; refcount[orphan_cluster]--; printf("DELETED\n"); } else if(refcount[orphan_cluster] < 1) { refcount[orphan_cluster]++; } orphan_cluster = get_fat_entry(orphan_cluster, image_buf, bpb); orphan_size++; } //got to concatanate stuff struct direntry *dirent = (struct direntry*)root_dir_addr(image_buf, bpb); char name[5]; sprintf(name, "%d", count); char str[1024] = ""; strcat(str, "located"); strcat(str, name); strcat(str, ".dat\0"); char * file_name = str; create_dirent(dirent, file_name, i, orphan_size * 512, image_buf, bpb); printf("added %s to directory \n", str); printf("orphan cluster chain size = %d \n", orphan_size); } } printf("orphans saved: %d\n", count); }
void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); printf("The address of the first dirent is: %lu\n", dirent); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(dirent, 0); if (is_valid_cluster(followclust, bpb)) follow_dir(followclust, 1, image_buf, bpb); dirent++; } }
void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(dirent, 0); if (is_valid_cluster(followclust, bpb)){ //dirent->deReferenceCount=1; follow_dir(followclust, 1, image_buf, bpb); } dirent++; } //printf("ReferenceCount= %d\n", dirent->deReferenceCount); }
void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); int i = 0; for ( ; i < numDirEntries; i++) { uint16_t followclust = print_dirent(dirent, indent); if (followclust) follow_dir(followclust, indent+1, image_buf, bpb); dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
void traverse_root(char * filename, uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(filename,dirent, 0); if (is_valid_cluster(followclust, bpb)) { follow_dir(filename, followclust, 1, image_buf, bpb); printf("Cluster is valid\n"); } dirent++; } printf("finished going through stuff\n"); // find_orphans(image_buf, bpb); }
/************PRINT_DIRENT***************/ uint16_t print_dirent(struct direntry *dirent, int indent, uint8_t *image_buf, struct bpb33* bpb, int *refcount ) { uint16_t followclust = 0; int i; char name[9]; char extension[4]; uint32_t size; uint16_t file_cluster; name[8] = ' '; extension[3] = ' '; memcpy(name, &(dirent->deName[0]), 8); memcpy(extension, dirent->deExtension, 3); if (name[0] == SLOT_EMPTY) { return followclust; } /* skip over deleted entries */ if (((uint8_t)name[0]) == SLOT_DELETED) { return followclust; } if (((uint8_t)name[0]) == 0x2E) { // dot entry ("." or "..") // skip it return followclust; } /* names are space padded - remove the spaces */ for (i = 8; i > 0; i--) { if (name[i] == ' ') name[i] = '\0'; else break; } /* remove the spaces from extensions */ for (i = 3; i > 0; i--) { if (extension[i] == ' ') extension[i] = '\0'; else break; } if ((dirent->deAttributes & ATTR_WIN95LFN) == ATTR_WIN95LFN) { // ignore any long file name extension entries // // printf("Win95 long-filename entry seq 0x%0x\n", dirent->deName[0]); } else if ((dirent->deAttributes & ATTR_VOLUME) != 0) { printf("Volume: %s\n", name); } else if ((dirent->deAttributes & ATTR_DIRECTORY) != 0) { // don't deal with hidden directories; MacOS makes these // for trash directories and such; just ignore them. if ((dirent->deAttributes & ATTR_HIDDEN) != ATTR_HIDDEN) { print_indent(indent); printf("%s/ (directory)\n", name); file_cluster = getushort(dirent->deStartCluster); followclust = file_cluster; } } else { /* * a "regular" file entry * print attributes, size, starting cluster, etc. */ int ro = (dirent->deAttributes & ATTR_READONLY) == ATTR_READONLY; int hidden = (dirent->deAttributes & ATTR_HIDDEN) == ATTR_HIDDEN; int sys = (dirent->deAttributes & ATTR_SYSTEM) == ATTR_SYSTEM; int arch = (dirent->deAttributes & ATTR_ARCHIVE) == ATTR_ARCHIVE; size = getulong(dirent->deFileSize); print_indent(indent); printf("%s.%s (%u bytes) (starting cluster %d) %c%c%c%c\n", name, extension, size, getushort(dirent->deStartCluster), ro?'r':' ', hidden?'h':' ', sys?'s':' ', arch?'a':' '); int cluster_count = 0; uint16_t curr_cluster = getushort(dirent->deStartCluster); uint16_t original_cluster = curr_cluster; uint16_t previous; while(is_valid_cluster(curr_cluster,bpb)) { refcount[curr_cluster]++; if(refcount[curr_cluster] > 1) //problem { printf("ERROR REFCOUNT > 1 FOR: %d, refcount = %d\n", curr_cluster, refcount[curr_cluster]); dirent->deName[0] = SLOT_DELETED; refcount[curr_cluster]--; } previous = curr_cluster; curr_cluster = get_fat_entry(curr_cluster, image_buf, bpb); if(previous == curr_cluster) //points to itself { printf("ERROR POINTS TO SELF\n"); set_fat_entry(curr_cluster, FAT12_MASK & CLUST_EOFS, image_buf, bpb); cluster_count++; break; } if(curr_cluster == (FAT12_MASK & CLUST_BAD)) { printf("BAD CLUSTER\n"); set_fat_entry(curr_cluster, FAT12_MASK & CLUST_FREE, image_buf, bpb); set_fat_entry(previous, FAT12_MASK & CLUST_EOFS, image_buf, bpb); break; } cluster_count++; } int clusters = 0; if(size%512 == 0) { clusters = size/512; } else { clusters = (size/512)+1; } if(clusters < cluster_count) { printf("ERROR: FILE SIZE TOO SMALL FOR NUM CLUSTERS\n"); curr_cluster = get_fat_entry(original_cluster+clusters - 1, image_buf, bpb); printf("FIXED \n"); while(is_valid_cluster(curr_cluster, bpb)) { previous = curr_cluster; set_fat_entry(previous, FAT12_MASK & CLUST_FREE, image_buf, bpb); curr_cluster = get_fat_entry(curr_cluster, image_buf, bpb); } set_fat_entry(original_cluster +clusters -1, FAT12_MASK &CLUST_EOFS, image_buf, bpb); } else if(clusters > cluster_count) { printf("ERROR: FILE SIZE TOO LARGE FOR NUM CLUSTERS\n"); uint32_t correct_size = cluster_count * bpb->bpbBytesPerSec; putulong(dirent->deFileSize, correct_size); printf("FIXED \n"); } } return followclust; }