예제 #1
0
파일: scandisk.c 프로젝트: mchav/ScanDisk
/*
 * 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);
    }
}
예제 #2
0
uint32_t get_file_length(uint16_t cluster, uint8_t *image_buf, struct bpb33* bpb)
{
    uint32_t length = 1;

    cluster = get_fat_entry(cluster, image_buf, bpb);
    while (!is_end_of_file(cluster)) {
        cluster = get_fat_entry(cluster, image_buf, bpb);
        length++;
    }

    return length;
}
예제 #3
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);
}
예제 #4
0
/************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);
    }
}
예제 #5
0
파일: scandisk.c 프로젝트: mchav/ScanDisk
/* 
 * 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);
    }
}
예제 #6
0
파일: scandisk.c 프로젝트: mchav/ScanDisk
/* 
 * 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;
}
예제 #7
0
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);
    }
}
예제 #8
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);
				}
			}
		}
	}
예제 #9
0
파일: scandisk.c 프로젝트: mchav/ScanDisk
/*
 * function that runs through the cluster list and stores orphans
 * in persistent memory
 */
void foster_orphans(uint8_t *image_buf, struct bpb33* bpb) {
    int orphan_count = 0;
    uint16_t curr_cluster = start_cluster;

    for ( ; curr_cluster < usable_clusters; curr_cluster++) {
        if ((get_fat_entry(curr_cluster, image_buf, bpb) != CLUST_FREE) 
            && !in_cluster_list(curr_cluster)) {
                orphan_count = foster_single_orphan(orphan_count, 
                                    curr_cluster, image_buf, bpb);
        }
    }
}
예제 #10
0
void mark_file_clusters_used(int usedClusters[], uint16_t cluster, uint32_t bytes_remaining, uint8_t *image_buf, struct bpb33* bpb)
{
    usedClusters[cluster] = 1;

    int clust_size = bpb->bpbSecPerClust * bpb->bpbBytesPerSec;
    int total_clusters = bpb->bpbSectors / bpb->bpbSecPerClust;

    if (cluster == 0) {
        fprintf(stderr, "Bad file termination\n");
        return;
    } else if (cluster > total_clusters) {
        abort(); /* this shouldn't be able to happen */
    }

    uint16_t next_cluster = get_fat_entry(cluster, image_buf, bpb);

    if (is_end_of_file(next_cluster)) {
        return;
    } else {
        mark_file_clusters_used(usedClusters, get_fat_entry(cluster, image_buf, bpb), bytes_remaining - clust_size, image_buf, bpb);
    }
}
예제 #11
0
파일: scandisk.c 프로젝트: mchav/ScanDisk
/*
 * calculate the size of a cluster chain
 */
uint32_t size_of_cluster(uint16_t cluster, uint8_t *image_buf, 
                         struct bpb33 *bpb) {
    uint16_t cluster_size = bpb->bpbBytesPerSec * bpb->bpbSecPerClust;
    uint32_t num_bytes = 0;
    append_clusters(cluster);
    while (!is_end_of_file(cluster)) {   
        if (cluster == bad_cluster) {
            printf("Bad cluster: cluster number %d \n\n", cluster);
        }
        num_bytes += cluster_size;
        cluster = get_fat_entry(cluster, image_buf, bpb);
        append_clusters(cluster);
    }
    return num_bytes;
}
예제 #12
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);
}
예제 #13
0
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);
    }
}
예제 #14
0
int* lookupSectors(int FLC, int * length, ubyte* image){

    int* sectors = (int*)malloc(10 * sizeof(int));
    int currEntry = FLC;
    int end = 0;
    *length = 1;

    sectors[0] = currEntry + 31;

    while (!end && *length <= 10)
    {
        currEntry = get_fat_entry(currEntry, (byte*)image);
        if(currEntry < 0xFF8){
            sectors[*length] = currEntry + 31;
            (*length)++;
        }
        else{
            end = 1;
        }
    }

    return sectors;
}
예제 #15
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;
}
예제 #16
0
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);
}
예제 #17
0
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);
        }
    }
}
예제 #18
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;
}
예제 #19
0
파일: read.c 프로젝트: jamjr/Helios-NG
 WORD read_from_file(WORD pos, WORD size, char *buf, FileInfo *info)
{ int to_read;
  int sector,	  /* no of sector to read */
      first_clus, /* 1st cluster to read */
      num, 	  /* no of cluster */
      begin, 	  /* pos of 1st byte in 1st cluster */
      i,
      nb_clus, 	  /* no total of cluster to read */
      reste,
      e;

  Wait( &Var_access );
    
#ifdef debug
    IOdebug("msdosfs : read_from_file(%s), %dbytes",info->Name,size);
#endif

  if( size == 0 ) 
  {
    Signal( &Var_access );
    return 0;
  }

  first_clus = pos / Cluster_byte;
  begin      = pos % Cluster_byte;
  num        = info->Cluster;

 		/* get cluster in chain */
  
  for(i = 0; i < first_clus; i++)
  {
	num = get_fat_entry(num);
	if(num < 0)
	   goto error;
	if( num >= 0xff8 )
	{
#ifdef debugE
	   IOdebug("msdosfs ERROR : read_from_file : eof unexpected");
#endif
	   goto error;
	}
  }

		/* read up to boundary of next cluster */

  to_read = (size > (Cluster_byte - begin)) ? Cluster_byte - begin : size;
  sector = (num - 2)*Cluster_size + Dir_start + Dir_size;
  e = flop_read(sector, Cluster_byte, buf);
  for(i = 0 ; i < to_read ; i++)
	buf[i] = buf[begin + i];
  if( e < to_read )
     goto error;
  buf += to_read;

		/* read full clusters */

  nb_clus = (size-to_read)/Cluster_byte;
  for(i=0; i<nb_clus; i++)
  {
	num = get_fat_entry(num);
	if( num<0 || num>=0xff8 ) goto error;
  	sector = (num - 2)*Cluster_size + Dir_start + Dir_size;
  	if(flop_read(sector, Cluster_byte, buf) < Cluster_byte ) 
	{
          Signal( &Var_access );
	  return (i*Cluster_byte + to_read);
        }
	buf += Cluster_byte;
  }

		/* read last cluster */

  reste = size - to_read - nb_clus*Cluster_byte;
  if(reste>0)
  {
        char *freeloc;
	char *tbuff=Malloc(Cluster_byte);
	if(tbuff == NULL)
		goto error;
	freeloc = tbuff;
	num = get_fat_entry(num);
	if( num<0 || num>=0xff8 )
		{
		Free(freeloc);
		goto error;
		}
  	sector = (num - 2)*Cluster_size + Dir_start + Dir_size;
  	e = flop_read(sector, Cluster_byte, tbuff);
  	for(i = 0 ; i < reste ; i++)
		*buf++ = *tbuff++;
	Free(freeloc);
  	if( e < reste ) 
	{
          Signal( &Var_access );
	  return (nb_clus*Cluster_byte + to_read);
	}
  }

  Signal( &Var_access );
  return(size);

 error :
  Signal( &Var_access );
  return(0);

}
예제 #20
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);
        }
    }
}