Esempio n. 1
0
/*
 * repair an inconsistent file
 */
void repair(struct direntry *dirent, uint8_t *image_buf, struct bpb33 *bpb, int actual_size) {
    
    uint16_t cluster = getushort(dirent->deStartCluster);
    uint16_t cluster_size = bpb->bpbBytesPerSec * bpb->bpbSecPerClust;
    uint16_t prev_cluster = cluster;

    uint16_t num_bytes = 0;
    
    // accumulate all the related clusters in the FAT
    while (num_bytes < actual_size) {
        num_bytes += cluster_size;
        prev_cluster = cluster;
        cluster = get_fat_entry(cluster, image_buf, bpb);
    }
    
    if (num_bytes != 0) {
        set_fat_entry(prev_cluster, eof_cluster, image_buf, bpb);
    }
    
    // update all other clusters attached and mark them as free
    while (!is_end_of_file(cluster)) {
        uint16_t old_cluster = cluster;
        cluster = get_fat_entry(cluster, image_buf, bpb);
        set_fat_entry(old_cluster, free_cluster, image_buf, bpb);
    }
}
Esempio n. 2
0
/* 
 * given a directory entry the function counts the number of
 * clusters referred to by the entry.
 */
int count_clusters(struct direntry *dirent, 
                   uint8_t *image_buf, struct bpb33 *bpb) {
    uint16_t cluster = getushort(dirent->deStartCluster);
    uint16_t cluster_size = bpb->bpbBytesPerSec * bpb->bpbSecPerClust;
    int num_bytes = 0; uint16_t prev_cluster = cluster;
    append_clusters(cluster);
    if (is_end_of_file(cluster)) num_bytes = 512;
    while (!is_end_of_file(cluster) && cluster < usable_clusters) {   
        if (cluster == bad_cluster) {
            printf("Bad cluster: cluster number %d \n\n", cluster);
            set_fat_entry(prev_cluster, eof_cluster, image_buf, bpb);
            break;
        }
        if (cluster == free_cluster) {
            set_fat_entry(prev_cluster, eof_cluster, image_buf, bpb);
            break;   
        }
        num_bytes += cluster_size;
        prev_cluster = cluster;
        cluster = get_fat_entry(cluster, image_buf, bpb);
        if (prev_cluster == cluster) {
            printf("Self referential cluster. \n\n");
            set_fat_entry(prev_cluster, eof_cluster, image_buf, bpb);
            break;   
        }
        append_clusters(cluster);
    }

    return num_bytes;
}
Esempio n. 3
0
void free_clusters(uint16_t cluster_begin, uint16_t cluster_end, uint8_t *image_buf, struct bpb33* bpb) {
    uint16_t current_cluster = cluster_begin;

    while(1) {
        uint16_t next_cluster = get_fat_entry(current_cluster, image_buf, bpb);

        set_fat_entry(current_cluster, FAT12_MASK&CLUST_FREE, image_buf, bpb);

        if (current_cluster == cluster_end || is_end_of_file(next_cluster)) {
            break;
        }

        current_cluster = next_cluster;
    }

    set_fat_entry(cluster_begin, FAT12_MASK&CLUST_EOFS, image_buf, bpb);
}
Esempio n. 4
0
void find_orphans(uint8_t *image_buf, struct bpb33* bpb) {//looks through the array we made and looks for clusters we didnt touch
	for(int i=0; i<4096, i++) {
		if (desperation[i]==0){
			if(get_fat_entry(i,image_buf,pbp)!=FAT12_MASK&CLUST_FREE) {
				//if finds one we didnt touch and it is not currently set free this will free it
				set_fat_entry(i, FAT12_MASK&CLUST_FREE, image_buf, bpb);
				}
			}
		}
	}
Esempio n. 5
0
/***********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);
}
Esempio n. 6
0
/************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;
}
Esempio n. 7
0
int compare(char *filename, uint16_t followclust, struct direntry *dirent, uint8_t *image_buf, struct bpb33* bpb){
	//will loop through fat until eof marking the good/bad/free clusters and freeing them
	uint32_t realsize = getulong(dirent->deFileSize);
	uint32_t clustersize = bpb->bpbSecPerClust*bpb->bpbBytesPerSec;
	int expected_num_clust = (realsize+511)/clustersize;  // finds num clusters according to the meta data
	
	//find actual num clusters in fat
	uint16_t fatent = get_fat_entry(followclust, image_buf, bpb);
	uint16_t prev_fatent = fatent;
	int count = 1;
	
	while(!is_end_of_file(fatent)) {  //loops through checking if eof
		uint16_t temp =get_fat_entry(fatent, image_buf, bpb);
		if (fatent == (FAT12_MASK & CLUST_BAD)){ //if the fatent is bad it will mark it in the array
			printf("Bad cluster");
			desperation[followclust+count]=-1;
			printf("File is inconsistant: name is: %s\n",filename);
			}
		
		

		if(count>=expected_num_clust)	//if we have more clusters than expected
			{	
			
			if (count==expected_num_clust) {  //will only happen once
				printf("count is greater\n");
				//will set the previous entry to be eof and fee the current cluster
				//will also set desperation =2 at the eof and 3 at the free cluster
				// this is becasue we want a record in desperation of free normal or not looked at clusters
				set_fat_entry(prev_fatent,FAT12_MASK&CLUST_EOFS, image_buf, bpb);
				desperation[followclust+count-1]=2;
				set_fat_entry(fatent, FAT12_MASK&CLUST_FREE, image_buf, bpb);
				desperation[followclust+count]=3;
				printf("file is inconsistant!!! name is: %s\n",filename);
			
				}
		
			else {
				// if we are over the size just free current cluster
				set_fat_entry(fatent, FAT12_MASK&CLUST_FREE, image_buf, bpb);
			
				}
			//when count is over expected we will put 3 in every cluster over size eof
			desperation[followclust+count]=3;
			fatent=temp;
			count++;
			}
		
		else {

			//if we are still running through the clusters then if we find a free set it as 3 or if it is just normal then set it as 1
			if (fatent == (FAT12_MASK&CLUST_FREE)) {
				printf("FREE CLUSTER BEFORE EOF WEEWOOWEEWOO");
				desperation[followclust+count]=3;
				
				}
			else {
				desperation[followclust+count]=1;
				}
			prev_fatent=fatent;
			fatent=get_fat_entry(fatent,image_buf, bpb);
			count++;
			}
			
		
		}
	desperation[followclust+count]=2;//set this block as an eof in desperation
	if (expected_num_clust>count){
		//if at the end cluster is greater than expected change the size in the meta data to be what the fat size is
		uint32_t clustersize = bpb->bpbSecPerClust*bpb->bpbBytesPerSec;
		putulong(dirent->deFileSize, (count*clustersize));
		printf("File is inconsistant!!! name is: %s \n", filename);
	}
	//loop through the current files clusters on desperation and until you hit the eof
	int i= followclust;
	int countgucci=0;
	while (desperation[i]!=2)
		{
		if (desperation[i]==1) {
			countgucci++;
			}
		}
	//put the newsize into the metadata
	putulong(dirent->deFileSize, (countgucci*clustersize));
	return count;
}