Revision 5fafdf24 block-vvfat.c

b/block-vvfat.c
1 1
/* vim:set shiftwidth=4 ts=8: */
2 2
/*
3 3
 * QEMU Block driver for virtual VFAT (shadows a local directory)
4
 * 
4
 *
5 5
 * Copyright (c) 2004,2005 Johannes E. Schindelin
6
 * 
6
 *
7 7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 8
 * of this software and associated documentation files (the "Software"), to deal
9 9
 * in the Software without restriction, including without limitation the rights
......
38 38
/* TODO: add ":bootsector=blabla.img:" */
39 39
/* LATER TODO: add automatic boot sector generation from
40 40
    BOOTEASY.ASM and Ranish Partition Manager
41
    Note that DOS assumes the system files to be the first files in the 
41
    Note that DOS assumes the system files to be the first files in the
42 42
    file system (test if the boot sector still relies on that fact)! */
43 43
/* MAYBE TODO: write block-visofs.c */
44 44
/* TODO: call try_commit() only after a timeout */
......
153 153
	    index_to<0 || index_to>=array->next ||
154 154
	    index_from<0 || index_from>=array->next)
155 155
	return -1;
156
    
156
   
157 157
    if(index_to==index_from)
158 158
	return 0;
159 159

  
......
167 167
	memmove(to+is*count,to,from-to);
168 168
    else
169 169
	memmove(from,from+is*count,to-from);
170
    
170
   
171 171
    memcpy(to,buf,is*count);
172 172

  
173 173
    free(buf);
......
319 319
    BlockDriverState* bs; /* pointer to parent */
320 320
    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
321 321
    unsigned char first_sectors[0x40*0x200];
322
    
322
   
323 323
    int fat_type; /* 16 or 32 */
324 324
    array_t fat,directory,mapping;
325
   
325
  
326 326
    unsigned int cluster_size;
327 327
    unsigned int sectors_per_cluster;
328 328
    unsigned int sectors_per_fat;
......
332 332
    uint32_t sector_count; /* total number of sectors of the partition */
333 333
    uint32_t cluster_count; /* total number of clusters of this partition */
334 334
    uint32_t max_fat_value;
335
   
335
  
336 336
    int current_fd;
337 337
    mapping_t* current_mapping;
338 338
    unsigned char* cluster; /* points to current cluster */
......
358 358
    partition_t* partition=&(real_mbr->partition[0]);
359 359

  
360 360
    memset(s->first_sectors,0,512);
361
   
361
  
362 362
    partition->attributes=0x80; /* bootable */
363 363
    partition->start_head=1;
364 364
    partition->start_sector=1;
......
478 478
    for(i=0;i<11;i++)
479 479
	chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0))
480 480
	    +(unsigned char)entry->name[i];
481
    
481
   
482 482
    return chksum;
483 483
}
484 484

  
......
554 554
		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
555 555
    }
556 556
    memset(s->fat.pointer,0,s->fat.size);
557
    
557
   
558 558
    switch(s->fat_type) {
559 559
	case 12: s->max_fat_value=0xfff; break;
560 560
	case 16: s->max_fat_value=0xffff; break;
......
579 579
	memcpy(entry->name,filename,strlen(filename));
580 580
	return entry;
581 581
    }
582
    
582
   
583 583
    entry_long=create_long_filename(s,filename);
584
  
585
    i = strlen(filename); 
584
 
585
    i = strlen(filename);
586 586
    for(j = i - 1; j>0  && filename[j]!='.';j--);
587 587
    if (j > 0)
588 588
	i = (j > 8 ? 8 : j);
......
592 592
    entry=array_get_next(&(s->directory));
593 593
    memset(entry->name,0x20,11);
594 594
    strncpy(entry->name,filename,i);
595
    
595
   
596 596
    if(j > 0)
597 597
	for (i = 0; i < 3 && filename[j+1+i]; i++)
598 598
	    entry->extension[i] = filename[j+1+i];
......
618 618
	if(entry1==entry) /* no dupe found */
619 619
	    break;
620 620

  
621
	/* use all 8 characters of name */	
621
	/* use all 8 characters of name */
622 622
	if(entry->name[7]==' ') {
623 623
	    int j;
624 624
	    for(j=6;j>0 && entry->name[j]==' ';j--)
......
675 675
	mapping->end = mapping->begin;
676 676
	return -1;
677 677
    }
678
   
678
  
679 679
    i = mapping->info.dir.first_dir_index =
680 680
	    first_cluster == 0 ? 0 : s->directory.next;
681 681

  
682
    /* actually read the directory, and allocate the mappings */ 
682
    /* actually read the directory, and allocate the mappings */
683 683
    while((entry=readdir(dir))) {
684 684
	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
685 685
        char* buffer;
......
690 690

  
691 691
	if(first_cluster == 0 && (is_dotdot || is_dot))
692 692
	    continue;
693
	
693

  
694 694
	buffer=(char*)malloc(length);
695 695
	assert(buffer);
696 696
	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
......
765 765
	memset(array_get(&(s->directory), cur), 0,
766 766
		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
767 767
    }
768
	
768

  
769 769
     /* reget the mapping, since s->mapping was possibly realloc()ed */
770 770
    mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
771 771
    first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
......
774 774

  
775 775
    direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
776 776
    set_begin_of_direntry(direntry, mapping->begin);
777
   
777
  
778 778
    return 0;
779 779
}
780 780

  
......
825 825
     */
826 826
    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
827 827
    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
828
    
828
   
829 829
    array_init(&(s->mapping),sizeof(mapping_t));
830 830
    array_init(&(s->directory),sizeof(direntry_t));
831 831

  
......
857 857

  
858 858
    for (i = 0, cluster = 0; i < s->mapping.next; i++) {
859 859
	int j;
860
	/* MS-DOS expects the FAT to be 0 for the root directory 
860
	/* MS-DOS expects the FAT to be 0 for the root directory
861 861
	 * (except for the media byte). */
862 862
	/* LATER TODO: still true for FAT32? */
863 863
	int fix_fat = (i != 0);
......
987 987
    s->qcow_filename = NULL;
988 988
    s->fat2 = NULL;
989 989
    s->downcase_short_names = 1;
990
    
990
   
991 991
    if (!strstart(dirname, "fat:", NULL))
992 992
	return -1;
993 993

  
......
1076 1076
	assert(index1<=index2);
1077 1077
	DLOG(mapping=array_get(&(s->mapping),index1);
1078 1078
	assert(mapping->begin<=cluster_num);
1079
	assert(index2 >= s->mapping.next || 
1079
	assert(index2 >= s->mapping.next ||
1080 1080
		((mapping = array_get(&(s->mapping),index2)) &&
1081 1081
		mapping->end>cluster_num)));
1082 1082
    }
......
1239 1239
}
1240 1240
#endif
1241 1241

  
1242
static int vvfat_read(BlockDriverState *bs, int64_t sector_num, 
1242
static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1243 1243
                    uint8_t *buf, int nb_sectors)
1244 1244
{
1245 1245
    BDRVVVFATState *s = bs->opaque;
......
1674 1674
}
1675 1675

  
1676 1676
/*
1677
 * This function looks at the modified data (qcow). 
1677
 * This function looks at the modified data (qcow).
1678 1678
 * It returns 0 upon inconsistency or error, and the number of clusters
1679 1679
 * used by the directory, its subdirectories and their files.
1680 1680
 */
......
1709 1709
    } else
1710 1710
	/* new directory */
1711 1711
	schedule_mkdir(s, cluster_num, strdup(path));
1712
		
1712
	
1713 1713
    lfn_init(&lfn);
1714 1714
    do {
1715 1715
	int i;
......
2049 2049
	    }
2050 2050

  
2051 2051
	    next_mapping->dir_index = mapping->dir_index;
2052
	    next_mapping->first_mapping_index = 
2052
	    next_mapping->first_mapping_index =
2053 2053
		mapping->first_mapping_index < 0 ?
2054 2054
		array_index(&(s->mapping), mapping) :
2055 2055
		mapping->first_mapping_index;
......
2069 2069

  
2070 2070
	    mapping = next_mapping;
2071 2071
	}
2072
		
2072
	
2073 2073
	cluster = c1;
2074 2074
    }
2075 2075

  
......
2555 2555
	return ret;
2556 2556
    }
2557 2557

  
2558
    /* copy FAT (with bdrv_read) */ 
2558
    /* copy FAT (with bdrv_read) */
2559 2559
    memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2560 2560

  
2561 2561
    /* recurse direntries from root (using bs->bdrv_read) */
......
2597 2597
    return do_commit(s);
2598 2598
}
2599 2599

  
2600
static int vvfat_write(BlockDriverState *bs, int64_t sector_num, 
2600
static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
2601 2601
                    const uint8_t *buf, int nb_sectors)
2602 2602
{
2603
    BDRVVVFATState *s = bs->opaque; 
2603
    BDRVVVFATState *s = bs->opaque;
2604 2604
    int i, ret;
2605 2605

  
2606 2606
DLOG(checkpoint());
......
2639 2639
		    begin = sector_num;
2640 2640
		if (end > sector_num + nb_sectors)
2641 2641
		    end = sector_num + nb_sectors;
2642
		dir_index  = mapping->dir_index + 
2642
		dir_index  = mapping->dir_index +
2643 2643
		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
2644 2644
		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
2645 2645

  
......
2698 2698
	*n = nb_sectors;
2699 2699
    else if (*n < 0)
2700 2700
	return 0;
2701
    return 1;	
2701
    return 1;
2702 2702
}
2703 2703

  
2704 2704
static int write_target_commit(BlockDriverState *bs, int64_t sector_num,

Also available in: Unified diff