/* * 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++; } }
/* * 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); } }
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); }
/* * helper function that fixes a single orphan and makes * a DAT file associated with the cluster */ int foster_single_orphan(int orphan_count, uint16_t curr_cluster, uint8_t *image_buf, struct bpb33* bpb) { orphan_count++; int cluster = 0; struct direntry* dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); char filename[13]; char str[3]; // make file name memset(filename, '\0', 13); strcat(filename, "found"); memset(str, '\0', 3); sprintf(str, "%d", orphan_count); strcat(filename, str); strcat(filename, ".dat"); int clusters_size = size_of_cluster(curr_cluster, image_buf, bpb); append_clusters(cluster); create_dirent(dirent, filename, curr_cluster, clusters_size, image_buf, bpb); return orphan_count; }
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); }
void check_lost_files(int usedClusters[], uint16_t cluster, uint8_t *image_buf, struct bpb33* bpb) { // A value of 1 means that the cluster is used somewhere. usedClusters[cluster] = 1; struct direntry *dirent; int d, i; dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); int clust_size = bpb->bpbBytesPerSec * bpb->bpbSecPerClust; while (1) { for (d = 0; d < clust_size; d += sizeof(struct direntry)) { 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; /* skip over deleted entries */ if (((uint8_t)name[0]) == SLOT_DELETED) continue; /* 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; } /* don't print "." or ".." directories */ if (strcmp(name, ".") == 0) { dirent++; continue; } if (strcmp(name, "..") == 0) { dirent++; continue; } if ((dirent->deAttributes & ATTR_VOLUME) != 0) { } else if ((dirent->deAttributes & ATTR_DIRECTORY) != 0) { file_cluster = getushort(dirent->deStartCluster); check_lost_files(usedClusters, file_cluster, image_buf, bpb); } else { /* We have a file. We should follow the file and remove all the used clusters from our collection! */ size = getulong(dirent->deFileSize); uint16_t file_cluster_begin = getushort(dirent->deStartCluster); //uint16_t cluster, uint32_t bytes_remaining, uint8_t *image_buf, struct bpb33* bpb mark_file_clusters_used(usedClusters, file_cluster_begin, size, image_buf, bpb); } dirent++; } /* We've reached the end of the cluster for this directory. Where's the next cluster? */ if (cluster == 0) { // root dir is special dirent++; } else { cluster = get_fat_entry(cluster, image_buf, bpb); dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); } } }
int main(int argc, char** argv) { uint8_t *image_buf; int fd; struct bpb33* bpb; if (argc != 2) { usage(); } image_buf = mmap_file(argv[1], &fd); bpb = check_bootsector(image_buf); int total_clusters = bpb->bpbSectors / bpb->bpbSecPerClust; int clust_size = bpb->bpbSecPerClust * bpb->bpbBytesPerSec; int used_clusters[total_clusters]; check_lost_files(used_clusters, 0, image_buf, bpb); int i; int shownPrefix = 0; for (i = 2; i < total_clusters; i++) { if (used_clusters[i] == 0 && get_fat_entry(i, image_buf, bpb) != CLUST_FREE) { if (!shownPrefix) { printf("Unreferenced:"); shownPrefix = 1; } printf(" %i", i); } if (i == total_clusters - 1 && shownPrefix) { printf("\n"); } } int foundCount = 1; shownPrefix = 0; for (i = 2; i < total_clusters; i++) { if (used_clusters[i] == 0 && get_fat_entry(i, image_buf, bpb) != CLUST_FREE) { if (!shownPrefix) { printf("Lost File: "); } uint16_t size = get_file_length(i, image_buf, bpb); printf("%i %i\n", i, size); struct direntry *dirent = (struct direntry*) cluster_to_addr(0, image_buf, bpb); uint32_t size_bytes = size * clust_size; const char base[] = "found"; const char extension[] = ".dat"; char filename [13]; sprintf(filename, "%s%i%s", base, foundCount++, extension); create_dirent(dirent, filename, i, size_bytes, image_buf, bpb); check_lost_files(used_clusters, 0, image_buf, bpb); } if (i == total_clusters - 1 && shownPrefix) { printf("\n"); } } check_file_length(0, image_buf, bpb); close(fd); exit(0); }
void check_file_length(uint16_t cluster, uint8_t *image_buf, struct bpb33* bpb) { struct direntry *dirent; int d, i; dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); int clust_size = bpb->bpbBytesPerSec * bpb->bpbSecPerClust; while (1) { for (d = 0; d < clust_size; d += sizeof(struct direntry)) { 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; /* skip over deleted entries */ if (((uint8_t)name[0]) == SLOT_DELETED) continue; /* 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; } /* don't print "." or ".." directories */ if (strcmp(name, ".") == 0) { dirent++; continue; } if (strcmp(name, "..") == 0) { dirent++; continue; } if ((dirent->deAttributes & ATTR_VOLUME) != 0) { continue; } else if ((dirent->deAttributes & ATTR_DIRECTORY) != 0) { file_cluster = getushort(dirent->deStartCluster); check_file_length(file_cluster, image_buf, bpb); } else { size = getulong(dirent->deFileSize); file_cluster = getushort(dirent->deStartCluster); uint16_t fat_size_clusters = get_file_length(file_cluster, image_buf, bpb); uint32_t size_clusters = (size + (clust_size - 1)) / clust_size; uint32_t fat_size = fat_size_clusters * clust_size; if (size_clusters != fat_size_clusters) { printf("%s.%s %u %u\n", name, extension, size, fat_size); uint16_t begin_cluster = file_cluster + size_clusters - 1; uint16_t end_cluster = file_cluster + fat_size_clusters; free_clusters(begin_cluster, end_cluster, image_buf, bpb); } } dirent++; } /* We've reached the end of the cluster for this directory. Where's the next cluster? */ if (cluster == 0) { // root dir is special dirent++; } else { cluster = get_fat_entry(cluster, image_buf, bpb); dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); } } }