Home | History | Annotate | Download | only in block
      1 /* vim:set shiftwidth=4 ts=8: */
      2 /*
      3  * QEMU Block driver for virtual VFAT (shadows a local directory)
      4  *
      5  * Copyright (c) 2004,2005 Johannes E. Schindelin
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 #include <sys/stat.h>
     26 #include <dirent.h>
     27 #include "qemu-common.h"
     28 #include "block_int.h"
     29 #include "module.h"
     30 
     31 #ifndef S_IWGRP
     32 #define S_IWGRP 0
     33 #endif
     34 #ifndef S_IWOTH
     35 #define S_IWOTH 0
     36 #endif
     37 
     38 /* TODO: add ":bootsector=blabla.img:" */
     39 /* LATER TODO: add automatic boot sector generation from
     40     BOOTEASY.ASM and Ranish Partition Manager
     41     Note that DOS assumes the system files to be the first files in the
     42     file system (test if the boot sector still relies on that fact)! */
     43 /* MAYBE TODO: write block-visofs.c */
     44 /* TODO: call try_commit() only after a timeout */
     45 
     46 /* #define DEBUG */
     47 
     48 #ifdef DEBUG
     49 
     50 #define DLOG(a) a
     51 
     52 #undef stderr
     53 #define stderr STDERR
     54 FILE* stderr = NULL;
     55 
     56 static void checkpoint(void);
     57 
     58 #ifdef __MINGW32__
     59 void nonono(const char* file, int line, const char* msg) {
     60     fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
     61     exit(-5);
     62 }
     63 #undef assert
     64 #define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
     65 #endif
     66 
     67 #else
     68 
     69 #define DLOG(a)
     70 
     71 #endif
     72 
     73 /* dynamic array functions */
     74 typedef struct array_t {
     75     char* pointer;
     76     unsigned int size,next,item_size;
     77 } array_t;
     78 
     79 static inline void array_init(array_t* array,unsigned int item_size)
     80 {
     81     array->pointer = NULL;
     82     array->size=0;
     83     array->next=0;
     84     array->item_size=item_size;
     85 }
     86 
     87 static inline void array_free(array_t* array)
     88 {
     89     if(array->pointer)
     90         free(array->pointer);
     91     array->size=array->next=0;
     92 }
     93 
     94 /* does not automatically grow */
     95 static inline void* array_get(array_t* array,unsigned int index) {
     96     assert(index < array->next);
     97     return array->pointer + index * array->item_size;
     98 }
     99 
    100 static inline int array_ensure_allocated(array_t* array, int index)
    101 {
    102     if((index + 1) * array->item_size > array->size) {
    103 	int new_size = (index + 32) * array->item_size;
    104 	array->pointer = qemu_realloc(array->pointer, new_size);
    105 	if (!array->pointer)
    106 	    return -1;
    107 	array->size = new_size;
    108 	array->next = index + 1;
    109     }
    110 
    111     return 0;
    112 }
    113 
    114 static inline void* array_get_next(array_t* array) {
    115     unsigned int next = array->next;
    116     void* result;
    117 
    118     if (array_ensure_allocated(array, next) < 0)
    119 	return NULL;
    120 
    121     array->next = next + 1;
    122     result = array_get(array, next);
    123 
    124     return result;
    125 }
    126 
    127 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
    128     if((array->next+count)*array->item_size>array->size) {
    129 	int increment=count*array->item_size;
    130 	array->pointer=qemu_realloc(array->pointer,array->size+increment);
    131 	if(!array->pointer)
    132             return NULL;
    133 	array->size+=increment;
    134     }
    135     memmove(array->pointer+(index+count)*array->item_size,
    136 		array->pointer+index*array->item_size,
    137 		(array->next-index)*array->item_size);
    138     array->next+=count;
    139     return array->pointer+index*array->item_size;
    140 }
    141 
    142 /* this performs a "roll", so that the element which was at index_from becomes
    143  * index_to, but the order of all other elements is preserved. */
    144 static inline int array_roll(array_t* array,int index_to,int index_from,int count)
    145 {
    146     char* buf;
    147     char* from;
    148     char* to;
    149     int is;
    150 
    151     if(!array ||
    152 	    index_to<0 || index_to>=array->next ||
    153 	    index_from<0 || index_from>=array->next)
    154 	return -1;
    155 
    156     if(index_to==index_from)
    157 	return 0;
    158 
    159     is=array->item_size;
    160     from=array->pointer+index_from*is;
    161     to=array->pointer+index_to*is;
    162     buf=qemu_malloc(is*count);
    163     memcpy(buf,from,is*count);
    164 
    165     if(index_to<index_from)
    166 	memmove(to+is*count,to,from-to);
    167     else
    168 	memmove(from,from+is*count,to-from);
    169 
    170     memcpy(to,buf,is*count);
    171 
    172     free(buf);
    173 
    174     return 0;
    175 }
    176 
    177 static inline int array_remove_slice(array_t* array,int index, int count)
    178 {
    179     assert(index >=0);
    180     assert(count > 0);
    181     assert(index + count <= array->next);
    182     if(array_roll(array,array->next-1,index,count))
    183 	return -1;
    184     array->next -= count;
    185     return 0;
    186 }
    187 
    188 static int array_remove(array_t* array,int index)
    189 {
    190     return array_remove_slice(array, index, 1);
    191 }
    192 
    193 /* return the index for a given member */
    194 static int array_index(array_t* array, void* pointer)
    195 {
    196     size_t offset = (char*)pointer - array->pointer;
    197     assert((offset % array->item_size) == 0);
    198     assert(offset/array->item_size < array->next);
    199     return offset/array->item_size;
    200 }
    201 
    202 /* These structures are used to fake a disk and the VFAT filesystem.
    203  * For this reason we need to use __attribute__((packed)). */
    204 
    205 typedef struct bootsector_t {
    206     uint8_t jump[3];
    207     uint8_t name[8];
    208     uint16_t sector_size;
    209     uint8_t sectors_per_cluster;
    210     uint16_t reserved_sectors;
    211     uint8_t number_of_fats;
    212     uint16_t root_entries;
    213     uint16_t total_sectors16;
    214     uint8_t media_type;
    215     uint16_t sectors_per_fat;
    216     uint16_t sectors_per_track;
    217     uint16_t number_of_heads;
    218     uint32_t hidden_sectors;
    219     uint32_t total_sectors;
    220     union {
    221         struct {
    222 	    uint8_t drive_number;
    223 	    uint8_t current_head;
    224 	    uint8_t signature;
    225 	    uint32_t id;
    226 	    uint8_t volume_label[11];
    227 	} __attribute__((packed)) fat16;
    228 	struct {
    229 	    uint32_t sectors_per_fat;
    230 	    uint16_t flags;
    231 	    uint8_t major,minor;
    232 	    uint32_t first_cluster_of_root_directory;
    233 	    uint16_t info_sector;
    234 	    uint16_t backup_boot_sector;
    235 	    uint16_t ignored;
    236 	} __attribute__((packed)) fat32;
    237     } u;
    238     uint8_t fat_type[8];
    239     uint8_t ignored[0x1c0];
    240     uint8_t magic[2];
    241 } __attribute__((packed)) bootsector_t;
    242 
    243 typedef struct {
    244     uint8_t head;
    245     uint8_t sector;
    246     uint8_t cylinder;
    247 } mbr_chs_t;
    248 
    249 typedef struct partition_t {
    250     uint8_t attributes; /* 0x80 = bootable */
    251     mbr_chs_t start_CHS;
    252     uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
    253     mbr_chs_t end_CHS;
    254     uint32_t start_sector_long;
    255     uint32_t length_sector_long;
    256 } __attribute__((packed)) partition_t;
    257 
    258 typedef struct mbr_t {
    259     uint8_t ignored[0x1b8];
    260     uint32_t nt_id;
    261     uint8_t ignored2[2];
    262     partition_t partition[4];
    263     uint8_t magic[2];
    264 } __attribute__((packed)) mbr_t;
    265 
    266 typedef struct direntry_t {
    267     uint8_t name[8];
    268     uint8_t extension[3];
    269     uint8_t attributes;
    270     uint8_t reserved[2];
    271     uint16_t ctime;
    272     uint16_t cdate;
    273     uint16_t adate;
    274     uint16_t begin_hi;
    275     uint16_t mtime;
    276     uint16_t mdate;
    277     uint16_t begin;
    278     uint32_t size;
    279 } __attribute__((packed)) direntry_t;
    280 
    281 /* this structure are used to transparently access the files */
    282 
    283 typedef struct mapping_t {
    284     /* begin is the first cluster, end is the last+1 */
    285     uint32_t begin,end;
    286     /* as s->directory is growable, no pointer may be used here */
    287     unsigned int dir_index;
    288     /* the clusters of a file may be in any order; this points to the first */
    289     int first_mapping_index;
    290     union {
    291 	/* offset is
    292 	 * - the offset in the file (in clusters) for a file, or
    293 	 * - the next cluster of the directory for a directory, and
    294 	 * - the address of the buffer for a faked entry
    295 	 */
    296 	struct {
    297 	    uint32_t offset;
    298 	} file;
    299 	struct {
    300 	    int parent_mapping_index;
    301 	    int first_dir_index;
    302 	} dir;
    303     } info;
    304     /* path contains the full path, i.e. it always starts with s->path */
    305     char* path;
    306 
    307     enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
    308 	MODE_DIRECTORY = 4, MODE_FAKED = 8,
    309 	MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
    310     int read_only;
    311 } mapping_t;
    312 
    313 #ifdef DEBUG
    314 static void print_direntry(const struct direntry_t*);
    315 static void print_mapping(const struct mapping_t* mapping);
    316 #endif
    317 
    318 /* here begins the real VVFAT driver */
    319 
    320 typedef struct BDRVVVFATState {
    321     BlockDriverState* bs; /* pointer to parent */
    322     unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
    323     unsigned char first_sectors[0x40*0x200];
    324 
    325     int fat_type; /* 16 or 32 */
    326     array_t fat,directory,mapping;
    327 
    328     unsigned int cluster_size;
    329     unsigned int sectors_per_cluster;
    330     unsigned int sectors_per_fat;
    331     unsigned int sectors_of_root_directory;
    332     uint32_t last_cluster_of_root_directory;
    333     unsigned int faked_sectors; /* how many sectors are faked before file data */
    334     uint32_t sector_count; /* total number of sectors of the partition */
    335     uint32_t cluster_count; /* total number of clusters of this partition */
    336     uint32_t max_fat_value;
    337 
    338     int current_fd;
    339     mapping_t* current_mapping;
    340     unsigned char* cluster; /* points to current cluster */
    341     unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
    342     unsigned int current_cluster;
    343 
    344     /* write support */
    345     BlockDriverState* write_target;
    346     char* qcow_filename;
    347     BlockDriverState* qcow;
    348     void* fat2;
    349     char* used_clusters;
    350     array_t commits;
    351     const char* path;
    352     int downcase_short_names;
    353 } BDRVVVFATState;
    354 
    355 /* take the sector position spos and convert it to Cylinder/Head/Sector position
    356  * if the position is outside the specified geometry, fill maximum value for CHS
    357  * and return 1 to signal overflow.
    358  */
    359 static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
    360     int head,sector;
    361     sector   = spos % (bs->secs);  spos/= bs->secs;
    362     head     = spos % (bs->heads); spos/= bs->heads;
    363     if(spos >= bs->cyls){
    364         /* Overflow,
    365         it happens if 32bit sector positions are used, while CHS is only 24bit.
    366         Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
    367         chs->head     = 0xFF;
    368         chs->sector   = 0xFF;
    369         chs->cylinder = 0xFF;
    370         return 1;
    371     }
    372     chs->head     = (uint8_t)head;
    373     chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
    374     chs->cylinder = (uint8_t)spos;
    375     return 0;
    376 }
    377 
    378 static void init_mbr(BDRVVVFATState* s)
    379 {
    380     /* TODO: if the files mbr.img and bootsect.img exist, use them */
    381     mbr_t* real_mbr=(mbr_t*)s->first_sectors;
    382     partition_t* partition = &(real_mbr->partition[0]);
    383     int lba;
    384 
    385     memset(s->first_sectors,0,512);
    386 
    387     /* Win NT Disk Signature */
    388     real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
    389 
    390     partition->attributes=0x80; /* bootable */
    391 
    392     /* LBA is used when partition is outside the CHS geometry */
    393     lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
    394     lba|= sector2CHS(s->bs, &partition->end_CHS,   s->sector_count);
    395 
    396     /*LBA partitions are identified only by start/length_sector_long not by CHS*/
    397     partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
    398     partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
    399 
    400     /* FAT12/FAT16/FAT32 */
    401     /* DOS uses different types when partition is LBA,
    402        probably to prevent older versions from using CHS on them */
    403     partition->fs_type= s->fat_type==12 ? 0x1:
    404                         s->fat_type==16 ? (lba?0xe:0x06):
    405                          /*fat_tyoe==32*/ (lba?0xc:0x0b);
    406 
    407     real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
    408 }
    409 
    410 /* direntry functions */
    411 
    412 /* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
    413 static inline int short2long_name(char* dest,const char* src)
    414 {
    415     int i;
    416     int len;
    417     for(i=0;i<129 && src[i];i++) {
    418         dest[2*i]=src[i];
    419 	dest[2*i+1]=0;
    420     }
    421     len=2*i;
    422     dest[2*i]=dest[2*i+1]=0;
    423     for(i=2*i+2;(i%26);i++)
    424 	dest[i]=0xff;
    425     return len;
    426 }
    427 
    428 static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
    429 {
    430     char buffer[258];
    431     int length=short2long_name(buffer,filename),
    432         number_of_entries=(length+25)/26,i;
    433     direntry_t* entry;
    434 
    435     for(i=0;i<number_of_entries;i++) {
    436 	entry=array_get_next(&(s->directory));
    437 	entry->attributes=0xf;
    438 	entry->reserved[0]=0;
    439 	entry->begin=0;
    440 	entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
    441     }
    442     for(i=0;i<26*number_of_entries;i++) {
    443 	int offset=(i%26);
    444 	if(offset<10) offset=1+offset;
    445 	else if(offset<22) offset=14+offset-10;
    446 	else offset=28+offset-22;
    447 	entry=array_get(&(s->directory),s->directory.next-1-(i/26));
    448 	entry->name[offset]=buffer[i];
    449     }
    450     return array_get(&(s->directory),s->directory.next-number_of_entries);
    451 }
    452 
    453 static char is_free(const direntry_t* direntry)
    454 {
    455     return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
    456 }
    457 
    458 static char is_volume_label(const direntry_t* direntry)
    459 {
    460     return direntry->attributes == 0x28;
    461 }
    462 
    463 static char is_long_name(const direntry_t* direntry)
    464 {
    465     return direntry->attributes == 0xf;
    466 }
    467 
    468 static char is_short_name(const direntry_t* direntry)
    469 {
    470     return !is_volume_label(direntry) && !is_long_name(direntry)
    471 	&& !is_free(direntry);
    472 }
    473 
    474 static char is_directory(const direntry_t* direntry)
    475 {
    476     return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
    477 }
    478 
    479 static inline char is_dot(const direntry_t* direntry)
    480 {
    481     return is_short_name(direntry) && direntry->name[0] == '.';
    482 }
    483 
    484 static char is_file(const direntry_t* direntry)
    485 {
    486     return is_short_name(direntry) && !is_directory(direntry);
    487 }
    488 
    489 static inline uint32_t begin_of_direntry(const direntry_t* direntry)
    490 {
    491     return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
    492 }
    493 
    494 static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
    495 {
    496     return le32_to_cpu(direntry->size);
    497 }
    498 
    499 static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
    500 {
    501     direntry->begin = cpu_to_le16(begin & 0xffff);
    502     direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
    503 }
    504 
    505 /* fat functions */
    506 
    507 static inline uint8_t fat_chksum(const direntry_t* entry)
    508 {
    509     uint8_t chksum=0;
    510     int i;
    511 
    512     for(i=0;i<11;i++) {
    513         unsigned char c;
    514 
    515         c = (i <= 8) ? entry->name[i] : entry->extension[i-8];
    516         chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
    517     }
    518 
    519     return chksum;
    520 }
    521 
    522 /* if return_time==0, this returns the fat_date, else the fat_time */
    523 static uint16_t fat_datetime(time_t time,int return_time) {
    524     struct tm* t;
    525 #ifdef _WIN32
    526     t=localtime(&time); /* this is not thread safe */
    527 #else
    528     struct tm t1;
    529     t = &t1;
    530     localtime_r(&time,t);
    531 #endif
    532     if(return_time)
    533 	return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
    534     return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
    535 }
    536 
    537 static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
    538 {
    539     if(s->fat_type==32) {
    540 	uint32_t* entry=array_get(&(s->fat),cluster);
    541 	*entry=cpu_to_le32(value);
    542     } else if(s->fat_type==16) {
    543 	uint16_t* entry=array_get(&(s->fat),cluster);
    544 	*entry=cpu_to_le16(value&0xffff);
    545     } else {
    546 	int offset = (cluster*3/2);
    547 	unsigned char* p = array_get(&(s->fat), offset);
    548         switch (cluster&1) {
    549 	case 0:
    550 		p[0] = value&0xff;
    551 		p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
    552 		break;
    553 	case 1:
    554 		p[0] = (p[0]&0xf) | ((value&0xf)<<4);
    555 		p[1] = (value>>4);
    556 		break;
    557 	}
    558     }
    559 }
    560 
    561 static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
    562 {
    563     if(s->fat_type==32) {
    564 	uint32_t* entry=array_get(&(s->fat),cluster);
    565 	return le32_to_cpu(*entry);
    566     } else if(s->fat_type==16) {
    567 	uint16_t* entry=array_get(&(s->fat),cluster);
    568 	return le16_to_cpu(*entry);
    569     } else {
    570 	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
    571 	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
    572     }
    573 }
    574 
    575 static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
    576 {
    577     if(fat_entry>s->max_fat_value-8)
    578 	return -1;
    579     return 0;
    580 }
    581 
    582 static inline void init_fat(BDRVVVFATState* s)
    583 {
    584     if (s->fat_type == 12) {
    585 	array_init(&(s->fat),1);
    586 	array_ensure_allocated(&(s->fat),
    587 		s->sectors_per_fat * 0x200 * 3 / 2 - 1);
    588     } else {
    589 	array_init(&(s->fat),(s->fat_type==32?4:2));
    590 	array_ensure_allocated(&(s->fat),
    591 		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
    592     }
    593     memset(s->fat.pointer,0,s->fat.size);
    594 
    595     switch(s->fat_type) {
    596 	case 12: s->max_fat_value=0xfff; break;
    597 	case 16: s->max_fat_value=0xffff; break;
    598 	case 32: s->max_fat_value=0x0fffffff; break;
    599 	default: s->max_fat_value=0; /* error... */
    600     }
    601 
    602 }
    603 
    604 /* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
    605 /* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
    606 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
    607 	unsigned int directory_start, const char* filename, int is_dot)
    608 {
    609     int i,j,long_index=s->directory.next;
    610     direntry_t* entry = NULL;
    611     direntry_t* entry_long = NULL;
    612 
    613     if(is_dot) {
    614 	entry=array_get_next(&(s->directory));
    615 	memset(entry->name,0x20,11);
    616 	memcpy(entry->name,filename,strlen(filename));
    617 	return entry;
    618     }
    619 
    620     entry_long=create_long_filename(s,filename);
    621 
    622     i = strlen(filename);
    623     for(j = i - 1; j>0  && filename[j]!='.';j--);
    624     if (j > 0)
    625 	i = (j > 8 ? 8 : j);
    626     else if (i > 8)
    627 	i = 8;
    628 
    629     entry=array_get_next(&(s->directory));
    630     memset(entry->name,0x20,11);
    631     memcpy(entry->name, filename, i);
    632 
    633     if(j > 0)
    634 	for (i = 0; i < 3 && filename[j+1+i]; i++)
    635 	    entry->extension[i] = filename[j+1+i];
    636 
    637     /* upcase & remove unwanted characters */
    638     for(i=10;i>=0;i--) {
    639 	if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
    640 	if(entry->name[i]<=' ' || entry->name[i]>0x7f
    641 		|| strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
    642 	    entry->name[i]='_';
    643         else if(entry->name[i]>='a' && entry->name[i]<='z')
    644             entry->name[i]+='A'-'a';
    645     }
    646 
    647     /* mangle duplicates */
    648     while(1) {
    649 	direntry_t* entry1=array_get(&(s->directory),directory_start);
    650 	int j;
    651 
    652 	for(;entry1<entry;entry1++)
    653 	    if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
    654 		break; /* found dupe */
    655 	if(entry1==entry) /* no dupe found */
    656 	    break;
    657 
    658 	/* use all 8 characters of name */
    659 	if(entry->name[7]==' ') {
    660 	    int j;
    661 	    for(j=6;j>0 && entry->name[j]==' ';j--)
    662 		entry->name[j]='~';
    663 	}
    664 
    665 	/* increment number */
    666 	for(j=7;j>0 && entry->name[j]=='9';j--)
    667 	    entry->name[j]='0';
    668 	if(j>0) {
    669 	    if(entry->name[j]<'0' || entry->name[j]>'9')
    670 	        entry->name[j]='0';
    671 	    else
    672 	        entry->name[j]++;
    673 	}
    674     }
    675 
    676     /* calculate checksum; propagate to long name */
    677     if(entry_long) {
    678         uint8_t chksum=fat_chksum(entry);
    679 
    680 	/* calculate anew, because realloc could have taken place */
    681 	entry_long=array_get(&(s->directory),long_index);
    682 	while(entry_long<entry && is_long_name(entry_long)) {
    683 	    entry_long->reserved[1]=chksum;
    684 	    entry_long++;
    685 	}
    686     }
    687 
    688     return entry;
    689 }
    690 
    691 /*
    692  * Read a directory. (the index of the corresponding mapping must be passed).
    693  */
    694 static int read_directory(BDRVVVFATState* s, int mapping_index)
    695 {
    696     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
    697     direntry_t* direntry;
    698     const char* dirname = mapping->path;
    699     int first_cluster = mapping->begin;
    700     int parent_index = mapping->info.dir.parent_mapping_index;
    701     mapping_t* parent_mapping = (mapping_t*)
    702         (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
    703     int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
    704 
    705     DIR* dir=opendir(dirname);
    706     struct dirent* entry;
    707     int i;
    708 
    709     assert(mapping->mode & MODE_DIRECTORY);
    710 
    711     if(!dir) {
    712 	mapping->end = mapping->begin;
    713 	return -1;
    714     }
    715 
    716     i = mapping->info.dir.first_dir_index =
    717 	    first_cluster == 0 ? 0 : s->directory.next;
    718 
    719     /* actually read the directory, and allocate the mappings */
    720     while((entry=readdir(dir))) {
    721 	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
    722         char* buffer;
    723 	direntry_t* direntry;
    724         struct stat st;
    725 	int is_dot=!strcmp(entry->d_name,".");
    726 	int is_dotdot=!strcmp(entry->d_name,"..");
    727 
    728 	if(first_cluster == 0 && (is_dotdot || is_dot))
    729 	    continue;
    730 
    731 	buffer=(char*)qemu_malloc(length);
    732 	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
    733 
    734 	if(stat(buffer,&st)<0) {
    735 	    free(buffer);
    736             continue;
    737 	}
    738 
    739 	/* create directory entry for this file */
    740 	direntry=create_short_and_long_name(s, i, entry->d_name,
    741 		is_dot || is_dotdot);
    742 	direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
    743 	direntry->reserved[0]=direntry->reserved[1]=0;
    744 	direntry->ctime=fat_datetime(st.st_ctime,1);
    745 	direntry->cdate=fat_datetime(st.st_ctime,0);
    746 	direntry->adate=fat_datetime(st.st_atime,0);
    747 	direntry->begin_hi=0;
    748 	direntry->mtime=fat_datetime(st.st_mtime,1);
    749 	direntry->mdate=fat_datetime(st.st_mtime,0);
    750 	if(is_dotdot)
    751 	    set_begin_of_direntry(direntry, first_cluster_of_parent);
    752 	else if(is_dot)
    753 	    set_begin_of_direntry(direntry, first_cluster);
    754 	else
    755 	    direntry->begin=0; /* do that later */
    756         if (st.st_size > 0x7fffffff) {
    757 	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
    758 	    free(buffer);
    759 	    return -2;
    760         }
    761 	direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
    762 
    763 	/* create mapping for this file */
    764 	if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
    765 	    s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
    766 	    s->current_mapping->begin=0;
    767 	    s->current_mapping->end=st.st_size;
    768 	    /*
    769 	     * we get the direntry of the most recent direntry, which
    770 	     * contains the short name and all the relevant information.
    771 	     */
    772 	    s->current_mapping->dir_index=s->directory.next-1;
    773 	    s->current_mapping->first_mapping_index = -1;
    774 	    if (S_ISDIR(st.st_mode)) {
    775 		s->current_mapping->mode = MODE_DIRECTORY;
    776 		s->current_mapping->info.dir.parent_mapping_index =
    777 		    mapping_index;
    778 	    } else {
    779 		s->current_mapping->mode = MODE_UNDEFINED;
    780 		s->current_mapping->info.file.offset = 0;
    781 	    }
    782 	    s->current_mapping->path=buffer;
    783 	    s->current_mapping->read_only =
    784 		(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
    785 	}
    786     }
    787     closedir(dir);
    788 
    789     /* fill with zeroes up to the end of the cluster */
    790     while(s->directory.next%(0x10*s->sectors_per_cluster)) {
    791 	direntry_t* direntry=array_get_next(&(s->directory));
    792 	memset(direntry,0,sizeof(direntry_t));
    793     }
    794 
    795 /* TODO: if there are more entries, bootsector has to be adjusted! */
    796 #define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
    797     if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
    798 	/* root directory */
    799 	int cur = s->directory.next;
    800 	array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
    801 	memset(array_get(&(s->directory), cur), 0,
    802 		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
    803     }
    804 
    805      /* reget the mapping, since s->mapping was possibly realloc()ed */
    806     mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
    807     first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
    808 	* 0x20 / s->cluster_size;
    809     mapping->end = first_cluster;
    810 
    811     direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
    812     set_begin_of_direntry(direntry, mapping->begin);
    813 
    814     return 0;
    815 }
    816 
    817 static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
    818 {
    819     return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
    820 }
    821 
    822 static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
    823 {
    824     return s->faked_sectors + s->sectors_per_cluster * cluster_num;
    825 }
    826 
    827 static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
    828 {
    829     return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
    830 }
    831 
    832 #ifdef DBG
    833 static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
    834 {
    835     if(mapping->mode==MODE_UNDEFINED)
    836 	return 0;
    837     return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
    838 }
    839 #endif
    840 
    841 static int init_directories(BDRVVVFATState* s,
    842 	const char* dirname)
    843 {
    844     bootsector_t* bootsector;
    845     mapping_t* mapping;
    846     unsigned int i;
    847     unsigned int cluster;
    848 
    849     memset(&(s->first_sectors[0]),0,0x40*0x200);
    850 
    851     s->cluster_size=s->sectors_per_cluster*0x200;
    852     s->cluster_buffer=qemu_malloc(s->cluster_size);
    853 
    854     /*
    855      * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
    856      * where sc is sector_count,
    857      * spf is sectors_per_fat,
    858      * spc is sectors_per_clusters, and
    859      * fat_type = 12, 16 or 32.
    860      */
    861     i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
    862     s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
    863 
    864     array_init(&(s->mapping),sizeof(mapping_t));
    865     array_init(&(s->directory),sizeof(direntry_t));
    866 
    867     /* add volume label */
    868     {
    869 	direntry_t* entry=array_get_next(&(s->directory));
    870 	entry->attributes=0x28; /* archive | volume label */
    871 	memcpy(entry->name,"QEMU VVF",8);
    872 	memcpy(entry->extension,"AT ",3);
    873     }
    874 
    875     /* Now build FAT, and write back information into directory */
    876     init_fat(s);
    877 
    878     s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
    879     s->cluster_count=sector2cluster(s, s->sector_count);
    880 
    881     mapping = array_get_next(&(s->mapping));
    882     mapping->begin = 0;
    883     mapping->dir_index = 0;
    884     mapping->info.dir.parent_mapping_index = -1;
    885     mapping->first_mapping_index = -1;
    886     mapping->path = qemu_strdup(dirname);
    887     i = strlen(mapping->path);
    888     if (i > 0 && mapping->path[i - 1] == '/')
    889 	mapping->path[i - 1] = '\0';
    890     mapping->mode = MODE_DIRECTORY;
    891     mapping->read_only = 0;
    892     s->path = mapping->path;
    893 
    894     for (i = 0, cluster = 0; i < s->mapping.next; i++) {
    895 	/* MS-DOS expects the FAT to be 0 for the root directory
    896 	 * (except for the media byte). */
    897 	/* LATER TODO: still true for FAT32? */
    898 	int fix_fat = (i != 0);
    899 	mapping = array_get(&(s->mapping), i);
    900 
    901         if (mapping->mode & MODE_DIRECTORY) {
    902 	    mapping->begin = cluster;
    903 	    if(read_directory(s, i)) {
    904 		fprintf(stderr, "Could not read directory %s\n",
    905 			mapping->path);
    906 		return -1;
    907 	    }
    908 	    mapping = array_get(&(s->mapping), i);
    909 	} else {
    910 	    assert(mapping->mode == MODE_UNDEFINED);
    911 	    mapping->mode=MODE_NORMAL;
    912 	    mapping->begin = cluster;
    913 	    if (mapping->end > 0) {
    914 		direntry_t* direntry = array_get(&(s->directory),
    915 			mapping->dir_index);
    916 
    917 		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
    918 		set_begin_of_direntry(direntry, mapping->begin);
    919 	    } else {
    920 		mapping->end = cluster + 1;
    921 		fix_fat = 0;
    922 	    }
    923 	}
    924 
    925 	assert(mapping->begin < mapping->end);
    926 
    927 	/* next free cluster */
    928 	cluster = mapping->end;
    929 
    930 	if(cluster > s->cluster_count) {
    931 	    fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",
    932 		    s->fat_type,
    933 		    s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
    934 								: "2.88 MB"
    935 				      : "504MB");
    936 	    return -EINVAL;
    937 	}
    938 
    939 	/* fix fat for entry */
    940 	if (fix_fat) {
    941 	    int j;
    942 	    for(j = mapping->begin; j < mapping->end - 1; j++)
    943 		fat_set(s, j, j+1);
    944 	    fat_set(s, mapping->end - 1, s->max_fat_value);
    945 	}
    946     }
    947 
    948     mapping = array_get(&(s->mapping), 0);
    949     s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
    950     s->last_cluster_of_root_directory = mapping->end;
    951 
    952     /* the FAT signature */
    953     fat_set(s,0,s->max_fat_value);
    954     fat_set(s,1,s->max_fat_value);
    955 
    956     s->current_mapping = NULL;
    957 
    958     bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
    959     bootsector->jump[0]=0xeb;
    960     bootsector->jump[1]=0x3e;
    961     bootsector->jump[2]=0x90;
    962     memcpy(bootsector->name,"QEMU    ",8);
    963     bootsector->sector_size=cpu_to_le16(0x200);
    964     bootsector->sectors_per_cluster=s->sectors_per_cluster;
    965     bootsector->reserved_sectors=cpu_to_le16(1);
    966     bootsector->number_of_fats=0x2; /* number of FATs */
    967     bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
    968     bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
    969     bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
    970     s->fat.pointer[0] = bootsector->media_type;
    971     bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
    972     bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
    973     bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
    974     bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
    975     bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
    976 
    977     /* LATER TODO: if FAT32, this is wrong */
    978     bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
    979     bootsector->u.fat16.current_head=0;
    980     bootsector->u.fat16.signature=0x29;
    981     bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
    982 
    983     memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
    984     memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);
    985     bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
    986 
    987     return 0;
    988 }
    989 
    990 #ifdef DEBUG
    991 static BDRVVVFATState *vvv = NULL;
    992 #endif
    993 
    994 static int enable_write_target(BDRVVVFATState *s);
    995 static int is_consistent(BDRVVVFATState *s);
    996 
    997 static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
    998 {
    999     BDRVVVFATState *s = bs->opaque;
   1000     int floppy = 0;
   1001     int i;
   1002 
   1003 #ifdef DEBUG
   1004     vvv = s;
   1005 #endif
   1006 
   1007 DLOG(if (stderr == NULL) {
   1008     stderr = fopen("vvfat.log", "a");
   1009     setbuf(stderr, NULL);
   1010 })
   1011 
   1012     s->bs = bs;
   1013 
   1014     s->fat_type=16;
   1015     /* LATER TODO: if FAT32, adjust */
   1016     s->sectors_per_cluster=0x10;
   1017     /* 504MB disk*/
   1018     bs->cyls=1024; bs->heads=16; bs->secs=63;
   1019 
   1020     s->current_cluster=0xffffffff;
   1021 
   1022     s->first_sectors_number=0x40;
   1023     /* read only is the default for safety */
   1024     bs->read_only = 1;
   1025     s->qcow = s->write_target = NULL;
   1026     s->qcow_filename = NULL;
   1027     s->fat2 = NULL;
   1028     s->downcase_short_names = 1;
   1029 
   1030     if (!strstart(dirname, "fat:", NULL))
   1031 	return -1;
   1032 
   1033     if (strstr(dirname, ":floppy:")) {
   1034 	floppy = 1;
   1035 	s->fat_type = 12;
   1036 	s->first_sectors_number = 1;
   1037 	s->sectors_per_cluster=2;
   1038 	bs->cyls = 80; bs->heads = 2; bs->secs = 36;
   1039     }
   1040 
   1041     s->sector_count=bs->cyls*bs->heads*bs->secs;
   1042 
   1043     if (strstr(dirname, ":32:")) {
   1044 	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
   1045 	s->fat_type = 32;
   1046     } else if (strstr(dirname, ":16:")) {
   1047 	s->fat_type = 16;
   1048     } else if (strstr(dirname, ":12:")) {
   1049 	s->fat_type = 12;
   1050 	s->sector_count=2880;
   1051     }
   1052 
   1053     if (strstr(dirname, ":rw:")) {
   1054 	if (enable_write_target(s))
   1055 	    return -1;
   1056 	bs->read_only = 0;
   1057     }
   1058 
   1059     i = strrchr(dirname, ':') - dirname;
   1060     assert(i >= 3);
   1061     if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))
   1062 	/* workaround for DOS drive names */
   1063 	dirname += i-1;
   1064     else
   1065 	dirname += i+1;
   1066 
   1067     bs->total_sectors=bs->cyls*bs->heads*bs->secs;
   1068 
   1069     if(init_directories(s, dirname))
   1070 	return -1;
   1071 
   1072     s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
   1073 
   1074     if(s->first_sectors_number==0x40)
   1075 	init_mbr(s);
   1076 
   1077     /* for some reason or other, MS-DOS does not like to know about CHS... */
   1078     if (floppy)
   1079 	bs->heads = bs->cyls = bs->secs = 0;
   1080 
   1081     //    assert(is_consistent(s));
   1082     return 0;
   1083 }
   1084 
   1085 static inline void vvfat_close_current_file(BDRVVVFATState *s)
   1086 {
   1087     if(s->current_mapping) {
   1088 	s->current_mapping = NULL;
   1089 	if (s->current_fd) {
   1090 		close(s->current_fd);
   1091 		s->current_fd = 0;
   1092 	}
   1093     }
   1094     s->current_cluster = -1;
   1095 }
   1096 
   1097 /* mappings between index1 and index2-1 are supposed to be ordered
   1098  * return value is the index of the last mapping for which end>cluster_num
   1099  */
   1100 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
   1101 {
   1102     while(1) {
   1103         int index3;
   1104 	mapping_t* mapping;
   1105 	index3=(index1+index2)/2;
   1106 	mapping=array_get(&(s->mapping),index3);
   1107 	assert(mapping->begin < mapping->end);
   1108 	if(mapping->begin>=cluster_num) {
   1109 	    assert(index2!=index3 || index2==0);
   1110 	    if(index2==index3)
   1111 		return index1;
   1112 	    index2=index3;
   1113 	} else {
   1114 	    if(index1==index3)
   1115 		return mapping->end<=cluster_num ? index2 : index1;
   1116 	    index1=index3;
   1117 	}
   1118 	assert(index1<=index2);
   1119 	DLOG(mapping=array_get(&(s->mapping),index1);
   1120 	assert(mapping->begin<=cluster_num);
   1121 	assert(index2 >= s->mapping.next ||
   1122 		((mapping = array_get(&(s->mapping),index2)) &&
   1123 		mapping->end>cluster_num)));
   1124     }
   1125 }
   1126 
   1127 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
   1128 {
   1129     int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
   1130     mapping_t* mapping;
   1131     if(index>=s->mapping.next)
   1132         return NULL;
   1133     mapping=array_get(&(s->mapping),index);
   1134     if(mapping->begin>cluster_num)
   1135         return NULL;
   1136     assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
   1137     return mapping;
   1138 }
   1139 
   1140 /*
   1141  * This function simply compares path == mapping->path. Since the mappings
   1142  * are sorted by cluster, this is expensive: O(n).
   1143  */
   1144 static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
   1145 	const char* path)
   1146 {
   1147     int i;
   1148 
   1149     for (i = 0; i < s->mapping.next; i++) {
   1150 	mapping_t* mapping = array_get(&(s->mapping), i);
   1151 	if (mapping->first_mapping_index < 0 &&
   1152 		!strcmp(path, mapping->path))
   1153 	    return mapping;
   1154     }
   1155 
   1156     return NULL;
   1157 }
   1158 
   1159 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
   1160 {
   1161     if(!mapping)
   1162 	return -1;
   1163     if(!s->current_mapping ||
   1164 	    strcmp(s->current_mapping->path,mapping->path)) {
   1165 	/* open file */
   1166 	int fd = open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
   1167 	if(fd<0)
   1168 	    return -1;
   1169 	vvfat_close_current_file(s);
   1170 	s->current_fd = fd;
   1171 	s->current_mapping = mapping;
   1172     }
   1173     return 0;
   1174 }
   1175 
   1176 static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
   1177 {
   1178     if(s->current_cluster != cluster_num) {
   1179 	int result=0;
   1180 	off_t offset;
   1181 	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
   1182 	if(!s->current_mapping
   1183 		|| s->current_mapping->begin>cluster_num
   1184 		|| s->current_mapping->end<=cluster_num) {
   1185 	    /* binary search of mappings for file */
   1186 	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
   1187 
   1188 	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
   1189 
   1190 	    if (mapping && mapping->mode & MODE_DIRECTORY) {
   1191 		vvfat_close_current_file(s);
   1192 		s->current_mapping = mapping;
   1193 read_cluster_directory:
   1194 		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
   1195 		s->cluster = (unsigned char*)s->directory.pointer+offset
   1196 			+ 0x20*s->current_mapping->info.dir.first_dir_index;
   1197 		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
   1198 		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
   1199 		s->current_cluster = cluster_num;
   1200 		return 0;
   1201 	    }
   1202 
   1203 	    if(open_file(s,mapping))
   1204 		return -2;
   1205 	} else if (s->current_mapping->mode & MODE_DIRECTORY)
   1206 	    goto read_cluster_directory;
   1207 
   1208 	assert(s->current_fd);
   1209 
   1210 	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
   1211 	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
   1212 	    return -3;
   1213 	s->cluster=s->cluster_buffer;
   1214 	result=read(s->current_fd,s->cluster,s->cluster_size);
   1215 	if(result<0) {
   1216 	    s->current_cluster = -1;
   1217 	    return -1;
   1218 	}
   1219 	s->current_cluster = cluster_num;
   1220     }
   1221     return 0;
   1222 }
   1223 
   1224 #ifdef DEBUG
   1225 static void hexdump(const void* address, uint32_t len)
   1226 {
   1227     const unsigned char* p = address;
   1228     int i, j;
   1229 
   1230     for (i = 0; i < len; i += 16) {
   1231 	for (j = 0; j < 16 && i + j < len; j++)
   1232 	    fprintf(stderr, "%02x ", p[i + j]);
   1233 	for (; j < 16; j++)
   1234 	    fprintf(stderr, "   ");
   1235 	fprintf(stderr, " ");
   1236 	for (j = 0; j < 16 && i + j < len; j++)
   1237 	    fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
   1238 	fprintf(stderr, "\n");
   1239     }
   1240 }
   1241 
   1242 static void print_direntry(const direntry_t* direntry)
   1243 {
   1244     int j = 0;
   1245     char buffer[1024];
   1246 
   1247     fprintf(stderr, "direntry %p: ", direntry);
   1248     if(!direntry)
   1249 	return;
   1250     if(is_long_name(direntry)) {
   1251 	unsigned char* c=(unsigned char*)direntry;
   1252 	int i;
   1253 	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
   1254 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
   1255 	    ADD_CHAR(c[i]);
   1256 	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
   1257 	    ADD_CHAR(c[i]);
   1258 	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
   1259 	    ADD_CHAR(c[i]);
   1260 	buffer[j] = 0;
   1261 	fprintf(stderr, "%s\n", buffer);
   1262     } else {
   1263 	int i;
   1264 	for(i=0;i<11;i++)
   1265 	    ADD_CHAR(direntry->name[i]);
   1266 	buffer[j] = 0;
   1267 	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
   1268 		buffer,
   1269 		direntry->attributes,
   1270 		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
   1271     }
   1272 }
   1273 
   1274 static void print_mapping(const mapping_t* mapping)
   1275 {
   1276     fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
   1277         "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
   1278         mapping, mapping->begin, mapping->end, mapping->dir_index,
   1279         mapping->first_mapping_index, mapping->path, mapping->mode);
   1280 
   1281     if (mapping->mode & MODE_DIRECTORY)
   1282 	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
   1283     else
   1284 	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
   1285 }
   1286 #endif
   1287 
   1288 static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
   1289                     uint8_t *buf, int nb_sectors)
   1290 {
   1291     BDRVVVFATState *s = bs->opaque;
   1292     int i;
   1293 
   1294     for(i=0;i<nb_sectors;i++,sector_num++) {
   1295 	if (sector_num >= s->sector_count)
   1296 	   return -1;
   1297 	if (s->qcow) {
   1298 	    int n;
   1299 	    if (s->qcow->drv->bdrv_is_allocated(s->qcow,
   1300 			sector_num, nb_sectors-i, &n)) {
   1301 DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
   1302 		if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
   1303 		    return -1;
   1304 		i += n - 1;
   1305 		sector_num += n - 1;
   1306 		continue;
   1307 	    }
   1308 DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
   1309 	}
   1310 	if(sector_num<s->faked_sectors) {
   1311 	    if(sector_num<s->first_sectors_number)
   1312 		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
   1313 	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
   1314 		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
   1315 	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
   1316 		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
   1317 	} else {
   1318 	    uint32_t sector=sector_num-s->faked_sectors,
   1319 	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
   1320 	    cluster_num=sector/s->sectors_per_cluster;
   1321 	    if(read_cluster(s, cluster_num) != 0) {
   1322 		/* LATER TODO: strict: return -1; */
   1323 		memset(buf+i*0x200,0,0x200);
   1324 		continue;
   1325 	    }
   1326 	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
   1327 	}
   1328     }
   1329     return 0;
   1330 }
   1331 
   1332 /* LATER TODO: statify all functions */
   1333 
   1334 /*
   1335  * Idea of the write support (use snapshot):
   1336  *
   1337  * 1. check if all data is consistent, recording renames, modifications,
   1338  *    new files and directories (in s->commits).
   1339  *
   1340  * 2. if the data is not consistent, stop committing
   1341  *
   1342  * 3. handle renames, and create new files and directories (do not yet
   1343  *    write their contents)
   1344  *
   1345  * 4. walk the directories, fixing the mapping and direntries, and marking
   1346  *    the handled mappings as not deleted
   1347  *
   1348  * 5. commit the contents of the files
   1349  *
   1350  * 6. handle deleted files and directories
   1351  *
   1352  */
   1353 
   1354 typedef struct commit_t {
   1355     char* path;
   1356     union {
   1357 	struct { uint32_t cluster; } rename;
   1358 	struct { int dir_index; uint32_t modified_offset; } writeout;
   1359 	struct { uint32_t first_cluster; } new_file;
   1360 	struct { uint32_t cluster; } mkdir;
   1361     } param;
   1362     /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
   1363     enum {
   1364 	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
   1365     } action;
   1366 } commit_t;
   1367 
   1368 static void clear_commits(BDRVVVFATState* s)
   1369 {
   1370     int i;
   1371 DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
   1372     for (i = 0; i < s->commits.next; i++) {
   1373 	commit_t* commit = array_get(&(s->commits), i);
   1374 	assert(commit->path || commit->action == ACTION_WRITEOUT);
   1375 	if (commit->action != ACTION_WRITEOUT) {
   1376 	    assert(commit->path);
   1377 	    free(commit->path);
   1378 	} else
   1379 	    assert(commit->path == NULL);
   1380     }
   1381     s->commits.next = 0;
   1382 }
   1383 
   1384 static void schedule_rename(BDRVVVFATState* s,
   1385 	uint32_t cluster, char* new_path)
   1386 {
   1387     commit_t* commit = array_get_next(&(s->commits));
   1388     commit->path = new_path;
   1389     commit->param.rename.cluster = cluster;
   1390     commit->action = ACTION_RENAME;
   1391 }
   1392 
   1393 static void schedule_writeout(BDRVVVFATState* s,
   1394 	int dir_index, uint32_t modified_offset)
   1395 {
   1396     commit_t* commit = array_get_next(&(s->commits));
   1397     commit->path = NULL;
   1398     commit->param.writeout.dir_index = dir_index;
   1399     commit->param.writeout.modified_offset = modified_offset;
   1400     commit->action = ACTION_WRITEOUT;
   1401 }
   1402 
   1403 static void schedule_new_file(BDRVVVFATState* s,
   1404 	char* path, uint32_t first_cluster)
   1405 {
   1406     commit_t* commit = array_get_next(&(s->commits));
   1407     commit->path = path;
   1408     commit->param.new_file.first_cluster = first_cluster;
   1409     commit->action = ACTION_NEW_FILE;
   1410 }
   1411 
   1412 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
   1413 {
   1414     commit_t* commit = array_get_next(&(s->commits));
   1415     commit->path = path;
   1416     commit->param.mkdir.cluster = cluster;
   1417     commit->action = ACTION_MKDIR;
   1418 }
   1419 
   1420 typedef struct {
   1421     /*
   1422      * Since the sequence number is at most 0x3f, and the filename
   1423      * length is at most 13 times the sequence number, the maximal
   1424      * filename length is 0x3f * 13 bytes.
   1425      */
   1426     unsigned char name[0x3f * 13 + 1];
   1427     int checksum, len;
   1428     int sequence_number;
   1429 } long_file_name;
   1430 
   1431 static void lfn_init(long_file_name* lfn)
   1432 {
   1433    lfn->sequence_number = lfn->len = 0;
   1434    lfn->checksum = 0x100;
   1435 }
   1436 
   1437 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
   1438 static int parse_long_name(long_file_name* lfn,
   1439 	const direntry_t* direntry)
   1440 {
   1441     int i, j, offset;
   1442     const unsigned char* pointer = (const unsigned char*)direntry;
   1443 
   1444     if (!is_long_name(direntry))
   1445 	return 1;
   1446 
   1447     if (pointer[0] & 0x40) {
   1448 	lfn->sequence_number = pointer[0] & 0x3f;
   1449 	lfn->checksum = pointer[13];
   1450 	lfn->name[0] = 0;
   1451 	lfn->name[lfn->sequence_number * 13] = 0;
   1452     } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
   1453 	return -1;
   1454     else if (pointer[13] != lfn->checksum)
   1455 	return -2;
   1456     else if (pointer[12] || pointer[26] || pointer[27])
   1457 	return -3;
   1458 
   1459     offset = 13 * (lfn->sequence_number - 1);
   1460     for (i = 0, j = 1; i < 13; i++, j+=2) {
   1461 	if (j == 11)
   1462 	    j = 14;
   1463 	else if (j == 26)
   1464 	    j = 28;
   1465 
   1466 	if (pointer[j+1] == 0)
   1467 	    lfn->name[offset + i] = pointer[j];
   1468 	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
   1469 	    return -4;
   1470 	else
   1471 	    lfn->name[offset + i] = 0;
   1472     }
   1473 
   1474     if (pointer[0] & 0x40)
   1475 	lfn->len = offset + strlen((char*)lfn->name + offset);
   1476 
   1477     return 0;
   1478 }
   1479 
   1480 /* returns 0 if successful, >0 if no short_name, and <0 on error */
   1481 static int parse_short_name(BDRVVVFATState* s,
   1482 	long_file_name* lfn, direntry_t* direntry)
   1483 {
   1484     int i, j;
   1485 
   1486     if (!is_short_name(direntry))
   1487 	return 1;
   1488 
   1489     for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
   1490     for (i = 0; i <= j; i++) {
   1491 	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
   1492 	    return -1;
   1493 	else if (s->downcase_short_names)
   1494 	    lfn->name[i] = qemu_tolower(direntry->name[i]);
   1495 	else
   1496 	    lfn->name[i] = direntry->name[i];
   1497     }
   1498 
   1499     for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
   1500     if (j >= 0) {
   1501 	lfn->name[i++] = '.';
   1502 	lfn->name[i + j + 1] = '\0';
   1503 	for (;j >= 0; j--) {
   1504 	    if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
   1505 		return -2;
   1506 	    else if (s->downcase_short_names)
   1507 		lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
   1508 	    else
   1509 		lfn->name[i + j] = direntry->extension[j];
   1510 	}
   1511     } else
   1512 	lfn->name[i + j + 1] = '\0';
   1513 
   1514     lfn->len = strlen((char*)lfn->name);
   1515 
   1516     return 0;
   1517 }
   1518 
   1519 static inline uint32_t modified_fat_get(BDRVVVFATState* s,
   1520 	unsigned int cluster)
   1521 {
   1522     if (cluster < s->last_cluster_of_root_directory) {
   1523 	if (cluster + 1 == s->last_cluster_of_root_directory)
   1524 	    return s->max_fat_value;
   1525 	else
   1526 	    return cluster + 1;
   1527     }
   1528 
   1529     if (s->fat_type==32) {
   1530         uint32_t* entry=((uint32_t*)s->fat2)+cluster;
   1531         return le32_to_cpu(*entry);
   1532     } else if (s->fat_type==16) {
   1533         uint16_t* entry=((uint16_t*)s->fat2)+cluster;
   1534         return le16_to_cpu(*entry);
   1535     } else {
   1536         const uint8_t* x=s->fat2+cluster*3/2;
   1537         return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
   1538     }
   1539 }
   1540 
   1541 static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
   1542 {
   1543     int was_modified = 0;
   1544     int i, dummy;
   1545 
   1546     if (s->qcow == NULL)
   1547 	return 0;
   1548 
   1549     for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
   1550 	was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
   1551 		cluster2sector(s, cluster_num) + i, 1, &dummy);
   1552 
   1553     return was_modified;
   1554 }
   1555 
   1556 static const char* get_basename(const char* path)
   1557 {
   1558     char* basename = strrchr(path, '/');
   1559     if (basename == NULL)
   1560 	return path;
   1561     else
   1562 	return basename + 1; /* strip '/' */
   1563 }
   1564 
   1565 /*
   1566  * The array s->used_clusters holds the states of the clusters. If it is
   1567  * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
   1568  * was modified, bit 3 is set.
   1569  * If any cluster is allocated, but not part of a file or directory, this
   1570  * driver refuses to commit.
   1571  */
   1572 typedef enum {
   1573      USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
   1574 } used_t;
   1575 
   1576 /*
   1577  * get_cluster_count_for_direntry() not only determines how many clusters
   1578  * are occupied by direntry, but also if it was renamed or modified.
   1579  *
   1580  * A file is thought to be renamed *only* if there already was a file with
   1581  * exactly the same first cluster, but a different name.
   1582  *
   1583  * Further, the files/directories handled by this function are
   1584  * assumed to be *not* deleted (and *only* those).
   1585  */
   1586 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
   1587 	direntry_t* direntry, const char* path)
   1588 {
   1589     /*
   1590      * This is a little bit tricky:
   1591      * IF the guest OS just inserts a cluster into the file chain,
   1592      * and leaves the rest alone, (i.e. the original file had clusters
   1593      * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
   1594      *
   1595      * - do_commit will write the cluster into the file at the given
   1596      *   offset, but
   1597      *
   1598      * - the cluster which is overwritten should be moved to a later
   1599      *   position in the file.
   1600      *
   1601      * I am not aware that any OS does something as braindead, but this
   1602      * situation could happen anyway when not committing for a long time.
   1603      * Just to be sure that this does not bite us, detect it, and copy the
   1604      * contents of the clusters to-be-overwritten into the qcow.
   1605      */
   1606     int copy_it = 0;
   1607     int was_modified = 0;
   1608     int32_t ret = 0;
   1609 
   1610     uint32_t cluster_num = begin_of_direntry(direntry);
   1611     uint32_t offset = 0;
   1612     int first_mapping_index = -1;
   1613     mapping_t* mapping = NULL;
   1614     const char* basename2 = NULL;
   1615 
   1616     vvfat_close_current_file(s);
   1617 
   1618     /* the root directory */
   1619     if (cluster_num == 0)
   1620 	return 0;
   1621 
   1622     /* write support */
   1623     if (s->qcow) {
   1624 	basename2 = get_basename(path);
   1625 
   1626 	mapping = find_mapping_for_cluster(s, cluster_num);
   1627 
   1628 	if (mapping) {
   1629 	    const char* basename;
   1630 
   1631 	    assert(mapping->mode & MODE_DELETED);
   1632 	    mapping->mode &= ~MODE_DELETED;
   1633 
   1634 	    basename = get_basename(mapping->path);
   1635 
   1636 	    assert(mapping->mode & MODE_NORMAL);
   1637 
   1638 	    /* rename */
   1639 	    if (strcmp(basename, basename2))
   1640 		schedule_rename(s, cluster_num, qemu_strdup(path));
   1641 	} else if (is_file(direntry))
   1642 	    /* new file */
   1643 	    schedule_new_file(s, qemu_strdup(path), cluster_num);
   1644 	else {
   1645             abort();
   1646 	    return 0;
   1647 	}
   1648     }
   1649 
   1650     while(1) {
   1651 	if (s->qcow) {
   1652 	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
   1653 		if (mapping == NULL ||
   1654 			mapping->begin > cluster_num ||
   1655 			mapping->end <= cluster_num)
   1656 		mapping = find_mapping_for_cluster(s, cluster_num);
   1657 
   1658 
   1659 		if (mapping &&
   1660 			(mapping->mode & MODE_DIRECTORY) == 0) {
   1661 
   1662 		    /* was modified in qcow */
   1663 		    if (offset != mapping->info.file.offset + s->cluster_size
   1664 			    * (cluster_num - mapping->begin)) {
   1665 			/* offset of this cluster in file chain has changed */
   1666                         abort();
   1667 			copy_it = 1;
   1668 		    } else if (offset == 0) {
   1669 			const char* basename = get_basename(mapping->path);
   1670 
   1671 			if (strcmp(basename, basename2))
   1672 			    copy_it = 1;
   1673 			first_mapping_index = array_index(&(s->mapping), mapping);
   1674 		    }
   1675 
   1676 		    if (mapping->first_mapping_index != first_mapping_index
   1677 			    && mapping->info.file.offset > 0) {
   1678                         abort();
   1679 			copy_it = 1;
   1680 		    }
   1681 
   1682 		    /* need to write out? */
   1683 		    if (!was_modified && is_file(direntry)) {
   1684 			was_modified = 1;
   1685 			schedule_writeout(s, mapping->dir_index, offset);
   1686 		    }
   1687 		}
   1688 	    }
   1689 
   1690 	    if (copy_it) {
   1691 		int i, dummy;
   1692 		/*
   1693 		 * This is horribly inefficient, but that is okay, since
   1694 		 * it is rarely executed, if at all.
   1695 		 */
   1696 		int64_t offset = cluster2sector(s, cluster_num);
   1697 
   1698 		vvfat_close_current_file(s);
   1699 		for (i = 0; i < s->sectors_per_cluster; i++)
   1700 		    if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
   1701 				offset + i, 1, &dummy)) {
   1702 			if (vvfat_read(s->bs,
   1703 				    offset, s->cluster_buffer, 1))
   1704 			    return -1;
   1705 			if (s->qcow->drv->bdrv_write(s->qcow,
   1706 				    offset, s->cluster_buffer, 1))
   1707 			    return -2;
   1708 		    }
   1709 	    }
   1710 	}
   1711 
   1712 	ret++;
   1713 	if (s->used_clusters[cluster_num] & USED_ANY)
   1714 	    return 0;
   1715 	s->used_clusters[cluster_num] = USED_FILE;
   1716 
   1717 	cluster_num = modified_fat_get(s, cluster_num);
   1718 
   1719 	if (fat_eof(s, cluster_num))
   1720 	    return ret;
   1721 	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
   1722 	    return -1;
   1723 
   1724 	offset += s->cluster_size;
   1725     }
   1726 }
   1727 
   1728 /*
   1729  * This function looks at the modified data (qcow).
   1730  * It returns 0 upon inconsistency or error, and the number of clusters
   1731  * used by the directory, its subdirectories and their files.
   1732  */
   1733 static int check_directory_consistency(BDRVVVFATState *s,
   1734 	int cluster_num, const char* path)
   1735 {
   1736     int ret = 0;
   1737     unsigned char* cluster = qemu_malloc(s->cluster_size);
   1738     direntry_t* direntries = (direntry_t*)cluster;
   1739     mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
   1740 
   1741     long_file_name lfn;
   1742     int path_len = strlen(path);
   1743     char path2[PATH_MAX];
   1744 
   1745     assert(path_len < PATH_MAX); /* len was tested before! */
   1746     pstrcpy(path2, sizeof(path2), path);
   1747     path2[path_len] = '/';
   1748     path2[path_len + 1] = '\0';
   1749 
   1750     if (mapping) {
   1751 	const char* basename = get_basename(mapping->path);
   1752 	const char* basename2 = get_basename(path);
   1753 
   1754 	assert(mapping->mode & MODE_DIRECTORY);
   1755 
   1756 	assert(mapping->mode & MODE_DELETED);
   1757 	mapping->mode &= ~MODE_DELETED;
   1758 
   1759 	if (strcmp(basename, basename2))
   1760 	    schedule_rename(s, cluster_num, qemu_strdup(path));
   1761     } else
   1762 	/* new directory */
   1763 	schedule_mkdir(s, cluster_num, qemu_strdup(path));
   1764 
   1765     lfn_init(&lfn);
   1766     do {
   1767 	int i;
   1768 	int subret = 0;
   1769 
   1770 	ret++;
   1771 
   1772 	if (s->used_clusters[cluster_num] & USED_ANY) {
   1773 	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
   1774 	    return 0;
   1775 	}
   1776 	s->used_clusters[cluster_num] = USED_DIRECTORY;
   1777 
   1778 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
   1779 	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
   1780 		s->sectors_per_cluster);
   1781 	if (subret) {
   1782 	    fprintf(stderr, "Error fetching direntries\n");
   1783 	fail:
   1784 	    free(cluster);
   1785 	    return 0;
   1786 	}
   1787 
   1788 	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
   1789 	    int cluster_count = 0;
   1790 
   1791 DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));
   1792 	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
   1793 		    is_free(direntries + i))
   1794 		continue;
   1795 
   1796 	    subret = parse_long_name(&lfn, direntries + i);
   1797 	    if (subret < 0) {
   1798 		fprintf(stderr, "Error in long name\n");
   1799 		goto fail;
   1800 	    }
   1801 	    if (subret == 0 || is_free(direntries + i))
   1802 		continue;
   1803 
   1804 	    if (fat_chksum(direntries+i) != lfn.checksum) {
   1805 		subret = parse_short_name(s, &lfn, direntries + i);
   1806 		if (subret < 0) {
   1807 		    fprintf(stderr, "Error in short name (%d)\n", subret);
   1808 		    goto fail;
   1809 		}
   1810 		if (subret > 0 || !strcmp((char*)lfn.name, ".")
   1811 			|| !strcmp((char*)lfn.name, ".."))
   1812 		    continue;
   1813 	    }
   1814 	    lfn.checksum = 0x100; /* cannot use long name twice */
   1815 
   1816 	    if (path_len + 1 + lfn.len >= PATH_MAX) {
   1817 		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
   1818 		goto fail;
   1819 	    }
   1820             pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
   1821                     (char*)lfn.name);
   1822 
   1823 	    if (is_directory(direntries + i)) {
   1824 		if (begin_of_direntry(direntries + i) == 0) {
   1825 		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
   1826 		    goto fail;
   1827 		}
   1828 		cluster_count = check_directory_consistency(s,
   1829 			begin_of_direntry(direntries + i), path2);
   1830 		if (cluster_count == 0) {
   1831 		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
   1832 		    goto fail;
   1833 		}
   1834 	    } else if (is_file(direntries + i)) {
   1835 		/* check file size with FAT */
   1836 		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
   1837 		if (cluster_count !=
   1838 			(le32_to_cpu(direntries[i].size) + s->cluster_size
   1839 			 - 1) / s->cluster_size) {
   1840 		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
   1841 		    goto fail;
   1842 		}
   1843 	    } else
   1844                 abort(); /* cluster_count = 0; */
   1845 
   1846 	    ret += cluster_count;
   1847 	}
   1848 
   1849 	cluster_num = modified_fat_get(s, cluster_num);
   1850     } while(!fat_eof(s, cluster_num));
   1851 
   1852     free(cluster);
   1853     return ret;
   1854 }
   1855 
   1856 /* returns 1 on success */
   1857 static int is_consistent(BDRVVVFATState* s)
   1858 {
   1859     int i, check;
   1860     int used_clusters_count = 0;
   1861 
   1862 DLOG(checkpoint());
   1863     /*
   1864      * - get modified FAT
   1865      * - compare the two FATs (TODO)
   1866      * - get buffer for marking used clusters
   1867      * - recurse direntries from root (using bs->bdrv_read to make
   1868      *    sure to get the new data)
   1869      *   - check that the FAT agrees with the size
   1870      *   - count the number of clusters occupied by this directory and
   1871      *     its files
   1872      * - check that the cumulative used cluster count agrees with the
   1873      *   FAT
   1874      * - if all is fine, return number of used clusters
   1875      */
   1876     if (s->fat2 == NULL) {
   1877 	int size = 0x200 * s->sectors_per_fat;
   1878 	s->fat2 = qemu_malloc(size);
   1879 	memcpy(s->fat2, s->fat.pointer, size);
   1880     }
   1881     check = vvfat_read(s->bs,
   1882 	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
   1883     if (check) {
   1884 	fprintf(stderr, "Could not copy fat\n");
   1885 	return 0;
   1886     }
   1887     assert (s->used_clusters);
   1888     for (i = 0; i < sector2cluster(s, s->sector_count); i++)
   1889 	s->used_clusters[i] &= ~USED_ANY;
   1890 
   1891     clear_commits(s);
   1892 
   1893     /* mark every mapped file/directory as deleted.
   1894      * (check_directory_consistency() will unmark those still present). */
   1895     if (s->qcow)
   1896 	for (i = 0; i < s->mapping.next; i++) {
   1897 	    mapping_t* mapping = array_get(&(s->mapping), i);
   1898 	    if (mapping->first_mapping_index < 0)
   1899 		mapping->mode |= MODE_DELETED;
   1900 	}
   1901 
   1902     used_clusters_count = check_directory_consistency(s, 0, s->path);
   1903     if (used_clusters_count <= 0) {
   1904 	DLOG(fprintf(stderr, "problem in directory\n"));
   1905 	return 0;
   1906     }
   1907 
   1908     check = s->last_cluster_of_root_directory;
   1909     for (i = check; i < sector2cluster(s, s->sector_count); i++) {
   1910 	if (modified_fat_get(s, i)) {
   1911 	    if(!s->used_clusters[i]) {
   1912 		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
   1913 		return 0;
   1914 	    }
   1915 	    check++;
   1916 	}
   1917 
   1918 	if (s->used_clusters[i] == USED_ALLOCATED) {
   1919 	    /* allocated, but not used... */
   1920 	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
   1921 	    return 0;
   1922 	}
   1923     }
   1924 
   1925     if (check != used_clusters_count)
   1926 	return 0;
   1927 
   1928     return used_clusters_count;
   1929 }
   1930 
   1931 static inline void adjust_mapping_indices(BDRVVVFATState* s,
   1932 	int offset, int adjust)
   1933 {
   1934     int i;
   1935 
   1936     for (i = 0; i < s->mapping.next; i++) {
   1937 	mapping_t* mapping = array_get(&(s->mapping), i);
   1938 
   1939 #define ADJUST_MAPPING_INDEX(name) \
   1940 	if (mapping->name >= offset) \
   1941 	    mapping->name += adjust
   1942 
   1943 	ADJUST_MAPPING_INDEX(first_mapping_index);
   1944 	if (mapping->mode & MODE_DIRECTORY)
   1945 	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
   1946     }
   1947 }
   1948 
   1949 /* insert or update mapping */
   1950 static mapping_t* insert_mapping(BDRVVVFATState* s,
   1951 	uint32_t begin, uint32_t end)
   1952 {
   1953     /*
   1954      * - find mapping where mapping->begin >= begin,
   1955      * - if mapping->begin > begin: insert
   1956      *   - adjust all references to mappings!
   1957      * - else: adjust
   1958      * - replace name
   1959      */
   1960     int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
   1961     mapping_t* mapping = NULL;
   1962     mapping_t* first_mapping = array_get(&(s->mapping), 0);
   1963 
   1964     if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
   1965 	    && mapping->begin < begin) {
   1966 	mapping->end = begin;
   1967 	index++;
   1968 	mapping = array_get(&(s->mapping), index);
   1969     }
   1970     if (index >= s->mapping.next || mapping->begin > begin) {
   1971 	mapping = array_insert(&(s->mapping), index, 1);
   1972 	mapping->path = NULL;
   1973 	adjust_mapping_indices(s, index, +1);
   1974     }
   1975 
   1976     mapping->begin = begin;
   1977     mapping->end = end;
   1978 
   1979 DLOG(mapping_t* next_mapping;
   1980 assert(index + 1 >= s->mapping.next ||
   1981 ((next_mapping = array_get(&(s->mapping), index + 1)) &&
   1982  next_mapping->begin >= end)));
   1983 
   1984     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
   1985 	s->current_mapping = array_get(&(s->mapping),
   1986 		s->current_mapping - first_mapping);
   1987 
   1988     return mapping;
   1989 }
   1990 
   1991 static int remove_mapping(BDRVVVFATState* s, int mapping_index)
   1992 {
   1993     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
   1994     mapping_t* first_mapping = array_get(&(s->mapping), 0);
   1995 
   1996     /* free mapping */
   1997     if (mapping->first_mapping_index < 0)
   1998 	free(mapping->path);
   1999 
   2000     /* remove from s->mapping */
   2001     array_remove(&(s->mapping), mapping_index);
   2002 
   2003     /* adjust all references to mappings */
   2004     adjust_mapping_indices(s, mapping_index, -1);
   2005 
   2006     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
   2007 	s->current_mapping = array_get(&(s->mapping),
   2008 		s->current_mapping - first_mapping);
   2009 
   2010     return 0;
   2011 }
   2012 
   2013 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
   2014 {
   2015     int i;
   2016     for (i = 0; i < s->mapping.next; i++) {
   2017 	mapping_t* mapping = array_get(&(s->mapping), i);
   2018 	if (mapping->dir_index >= offset)
   2019 	    mapping->dir_index += adjust;
   2020 	if ((mapping->mode & MODE_DIRECTORY) &&
   2021 		mapping->info.dir.first_dir_index >= offset)
   2022 	    mapping->info.dir.first_dir_index += adjust;
   2023     }
   2024 }
   2025 
   2026 static direntry_t* insert_direntries(BDRVVVFATState* s,
   2027 	int dir_index, int count)
   2028 {
   2029     /*
   2030      * make room in s->directory,
   2031      * adjust_dirindices
   2032      */
   2033     direntry_t* result = array_insert(&(s->directory), dir_index, count);
   2034     if (result == NULL)
   2035 	return NULL;
   2036     adjust_dirindices(s, dir_index, count);
   2037     return result;
   2038 }
   2039 
   2040 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
   2041 {
   2042     int ret = array_remove_slice(&(s->directory), dir_index, count);
   2043     if (ret)
   2044 	return ret;
   2045     adjust_dirindices(s, dir_index, -count);
   2046     return 0;
   2047 }
   2048 
   2049 /*
   2050  * Adapt the mappings of the cluster chain starting at first cluster
   2051  * (i.e. if a file starts at first_cluster, the chain is followed according
   2052  * to the modified fat, and the corresponding entries in s->mapping are
   2053  * adjusted)
   2054  */
   2055 static int commit_mappings(BDRVVVFATState* s,
   2056 	uint32_t first_cluster, int dir_index)
   2057 {
   2058     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
   2059     direntry_t* direntry = array_get(&(s->directory), dir_index);
   2060     uint32_t cluster = first_cluster;
   2061 
   2062     vvfat_close_current_file(s);
   2063 
   2064     assert(mapping);
   2065     assert(mapping->begin == first_cluster);
   2066     mapping->first_mapping_index = -1;
   2067     mapping->dir_index = dir_index;
   2068     mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
   2069 	MODE_DIRECTORY : MODE_NORMAL;
   2070 
   2071     while (!fat_eof(s, cluster)) {
   2072 	uint32_t c, c1;
   2073 
   2074 	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
   2075 		c = c1, c1 = modified_fat_get(s, c1));
   2076 
   2077 	c++;
   2078 	if (c > mapping->end) {
   2079 	    int index = array_index(&(s->mapping), mapping);
   2080 	    int i, max_i = s->mapping.next - index;
   2081 	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
   2082 	    while (--i > 0)
   2083 		remove_mapping(s, index + 1);
   2084 	}
   2085 	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
   2086 		|| mapping[1].begin >= c);
   2087 	mapping->end = c;
   2088 
   2089 	if (!fat_eof(s, c1)) {
   2090 	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
   2091 	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
   2092 		array_get(&(s->mapping), i);
   2093 
   2094 	    if (next_mapping == NULL || next_mapping->begin > c1) {
   2095 		int i1 = array_index(&(s->mapping), mapping);
   2096 
   2097 		next_mapping = insert_mapping(s, c1, c1+1);
   2098 
   2099 		if (c1 < c)
   2100 		    i1++;
   2101 		mapping = array_get(&(s->mapping), i1);
   2102 	    }
   2103 
   2104 	    next_mapping->dir_index = mapping->dir_index;
   2105 	    next_mapping->first_mapping_index =
   2106 		mapping->first_mapping_index < 0 ?
   2107 		array_index(&(s->mapping), mapping) :
   2108 		mapping->first_mapping_index;
   2109 	    next_mapping->path = mapping->path;
   2110 	    next_mapping->mode = mapping->mode;
   2111 	    next_mapping->read_only = mapping->read_only;
   2112 	    if (mapping->mode & MODE_DIRECTORY) {
   2113 		next_mapping->info.dir.parent_mapping_index =
   2114 			mapping->info.dir.parent_mapping_index;
   2115 		next_mapping->info.dir.first_dir_index =
   2116 			mapping->info.dir.first_dir_index +
   2117 			0x10 * s->sectors_per_cluster *
   2118 			(mapping->end - mapping->begin);
   2119 	    } else
   2120 		next_mapping->info.file.offset = mapping->info.file.offset +
   2121 			mapping->end - mapping->begin;
   2122 
   2123 	    mapping = next_mapping;
   2124 	}
   2125 
   2126 	cluster = c1;
   2127     }
   2128 
   2129     return 0;
   2130 }
   2131 
   2132 static int commit_direntries(BDRVVVFATState* s,
   2133 	int dir_index, int parent_mapping_index)
   2134 {
   2135     direntry_t* direntry = array_get(&(s->directory), dir_index);
   2136     uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
   2137     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
   2138 
   2139     int factor = 0x10 * s->sectors_per_cluster;
   2140     int old_cluster_count, new_cluster_count;
   2141     int current_dir_index = mapping->info.dir.first_dir_index;
   2142     int first_dir_index = current_dir_index;
   2143     int ret, i;
   2144     uint32_t c;
   2145 
   2146 DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
   2147 
   2148     assert(direntry);
   2149     assert(mapping);
   2150     assert(mapping->begin == first_cluster);
   2151     assert(mapping->info.dir.first_dir_index < s->directory.next);
   2152     assert(mapping->mode & MODE_DIRECTORY);
   2153     assert(dir_index == 0 || is_directory(direntry));
   2154 
   2155     mapping->info.dir.parent_mapping_index = parent_mapping_index;
   2156 
   2157     if (first_cluster == 0) {
   2158 	old_cluster_count = new_cluster_count =
   2159 	    s->last_cluster_of_root_directory;
   2160     } else {
   2161 	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
   2162 		c = fat_get(s, c))
   2163 	    old_cluster_count++;
   2164 
   2165 	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
   2166 		c = modified_fat_get(s, c))
   2167 	    new_cluster_count++;
   2168     }
   2169 
   2170     if (new_cluster_count > old_cluster_count) {
   2171 	if (insert_direntries(s,
   2172 		current_dir_index + factor * old_cluster_count,
   2173 		factor * (new_cluster_count - old_cluster_count)) == NULL)
   2174 	    return -1;
   2175     } else if (new_cluster_count < old_cluster_count)
   2176 	remove_direntries(s,
   2177 		current_dir_index + factor * new_cluster_count,
   2178 		factor * (old_cluster_count - new_cluster_count));
   2179 
   2180     for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
   2181 	void* direntry = array_get(&(s->directory), current_dir_index);
   2182 	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
   2183 		s->sectors_per_cluster);
   2184 	if (ret)
   2185 	    return ret;
   2186 	assert(!strncmp(s->directory.pointer, "QEMU", 4));
   2187 	current_dir_index += factor;
   2188     }
   2189 
   2190     ret = commit_mappings(s, first_cluster, dir_index);
   2191     if (ret)
   2192 	return ret;
   2193 
   2194     /* recurse */
   2195     for (i = 0; i < factor * new_cluster_count; i++) {
   2196 	direntry = array_get(&(s->directory), first_dir_index + i);
   2197 	if (is_directory(direntry) && !is_dot(direntry)) {
   2198 	    mapping = find_mapping_for_cluster(s, first_cluster);
   2199 	    assert(mapping->mode & MODE_DIRECTORY);
   2200 	    ret = commit_direntries(s, first_dir_index + i,
   2201 		array_index(&(s->mapping), mapping));
   2202 	    if (ret)
   2203 		return ret;
   2204 	}
   2205     }
   2206 
   2207     return 0;
   2208 }
   2209 
   2210 /* commit one file (adjust contents, adjust mapping),
   2211    return first_mapping_index */
   2212 static int commit_one_file(BDRVVVFATState* s,
   2213 	int dir_index, uint32_t offset)
   2214 {
   2215     direntry_t* direntry = array_get(&(s->directory), dir_index);
   2216     uint32_t c = begin_of_direntry(direntry);
   2217     uint32_t first_cluster = c;
   2218     mapping_t* mapping = find_mapping_for_cluster(s, c);
   2219     uint32_t size = filesize_of_direntry(direntry);
   2220     char* cluster = qemu_malloc(s->cluster_size);
   2221     uint32_t i;
   2222     int fd = 0;
   2223 
   2224     assert(offset < size);
   2225     assert((offset % s->cluster_size) == 0);
   2226 
   2227     for (i = s->cluster_size; i < offset; i += s->cluster_size)
   2228 	c = modified_fat_get(s, c);
   2229 
   2230     fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
   2231     if (fd < 0) {
   2232 	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
   2233 		strerror(errno), errno);
   2234 	return fd;
   2235     }
   2236     if (offset > 0)
   2237 	if (lseek(fd, offset, SEEK_SET) != offset)
   2238 	    return -3;
   2239 
   2240     while (offset < size) {
   2241 	uint32_t c1;
   2242 	int rest_size = (size - offset > s->cluster_size ?
   2243 		s->cluster_size : size - offset);
   2244 	int ret;
   2245 
   2246 	c1 = modified_fat_get(s, c);
   2247 
   2248 	assert((size - offset == 0 && fat_eof(s, c)) ||
   2249 		(size > offset && c >=2 && !fat_eof(s, c)));
   2250 
   2251 	ret = vvfat_read(s->bs, cluster2sector(s, c),
   2252 	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
   2253 
   2254 	if (ret < 0)
   2255 	    return ret;
   2256 
   2257 	if (write(fd, cluster, rest_size) < 0)
   2258 	    return -2;
   2259 
   2260 	offset += rest_size;
   2261 	c = c1;
   2262     }
   2263 
   2264     if (ftruncate(fd, size)) {
   2265         perror("ftruncate()");
   2266         close(fd);
   2267         return -4;
   2268     }
   2269     close(fd);
   2270 
   2271     return commit_mappings(s, first_cluster, dir_index);
   2272 }
   2273 
   2274 #ifdef DEBUG
   2275 /* test, if all mappings point to valid direntries */
   2276 static void check1(BDRVVVFATState* s)
   2277 {
   2278     int i;
   2279     for (i = 0; i < s->mapping.next; i++) {
   2280 	mapping_t* mapping = array_get(&(s->mapping), i);
   2281 	if (mapping->mode & MODE_DELETED) {
   2282 	    fprintf(stderr, "deleted\n");
   2283 	    continue;
   2284 	}
   2285 	assert(mapping->dir_index >= 0);
   2286 	assert(mapping->dir_index < s->directory.next);
   2287 	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
   2288 	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
   2289 	if (mapping->mode & MODE_DIRECTORY) {
   2290 	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
   2291 	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
   2292 	}
   2293     }
   2294 }
   2295 
   2296 /* test, if all direntries have mappings */
   2297 static void check2(BDRVVVFATState* s)
   2298 {
   2299     int i;
   2300     int first_mapping = -1;
   2301 
   2302     for (i = 0; i < s->directory.next; i++) {
   2303 	direntry_t* direntry = array_get(&(s->directory), i);
   2304 
   2305 	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
   2306 	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
   2307 	    assert(mapping);
   2308 	    assert(mapping->dir_index == i || is_dot(direntry));
   2309 	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
   2310 	}
   2311 
   2312 	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
   2313 	    /* cluster start */
   2314 	    int j, count = 0;
   2315 
   2316 	    for (j = 0; j < s->mapping.next; j++) {
   2317 		mapping_t* mapping = array_get(&(s->mapping), j);
   2318 		if (mapping->mode & MODE_DELETED)
   2319 		    continue;
   2320 		if (mapping->mode & MODE_DIRECTORY) {
   2321 		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
   2322 			assert(++count == 1);
   2323 			if (mapping->first_mapping_index == -1)
   2324 			    first_mapping = array_index(&(s->mapping), mapping);
   2325 			else
   2326 			    assert(first_mapping == mapping->first_mapping_index);
   2327 			if (mapping->info.dir.parent_mapping_index < 0)
   2328 			    assert(j == 0);
   2329 			else {
   2330 			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
   2331 			    assert(parent->mode & MODE_DIRECTORY);
   2332 			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
   2333 			}
   2334 		    }
   2335 		}
   2336 	    }
   2337 	    if (count == 0)
   2338 		first_mapping = -1;
   2339 	}
   2340     }
   2341 }
   2342 #endif
   2343 
   2344 static int handle_renames_and_mkdirs(BDRVVVFATState* s)
   2345 {
   2346     int i;
   2347 
   2348 #ifdef DEBUG
   2349     fprintf(stderr, "handle_renames\n");
   2350     for (i = 0; i < s->commits.next; i++) {
   2351 	commit_t* commit = array_get(&(s->commits), i);
   2352 	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
   2353     }
   2354 #endif
   2355 
   2356     for (i = 0; i < s->commits.next;) {
   2357 	commit_t* commit = array_get(&(s->commits), i);
   2358 	if (commit->action == ACTION_RENAME) {
   2359 	    mapping_t* mapping = find_mapping_for_cluster(s,
   2360 		    commit->param.rename.cluster);
   2361 	    char* old_path = mapping->path;
   2362 
   2363 	    assert(commit->path);
   2364 	    mapping->path = commit->path;
   2365 	    if (rename(old_path, mapping->path))
   2366 		return -2;
   2367 
   2368 	    if (mapping->mode & MODE_DIRECTORY) {
   2369 		int l1 = strlen(mapping->path);
   2370 		int l2 = strlen(old_path);
   2371 		int diff = l1 - l2;
   2372 		direntry_t* direntry = array_get(&(s->directory),
   2373 			mapping->info.dir.first_dir_index);
   2374 		uint32_t c = mapping->begin;
   2375 		int i = 0;
   2376 
   2377 		/* recurse */
   2378 		while (!fat_eof(s, c)) {
   2379 		    do {
   2380 			direntry_t* d = direntry + i;
   2381 
   2382 			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
   2383 			    mapping_t* m = find_mapping_for_cluster(s,
   2384 				    begin_of_direntry(d));
   2385 			    int l = strlen(m->path);
   2386 			    char* new_path = qemu_malloc(l + diff + 1);
   2387 
   2388 			    assert(!strncmp(m->path, mapping->path, l2));
   2389 
   2390                             pstrcpy(new_path, l + diff + 1, mapping->path);
   2391                             pstrcpy(new_path + l1, l + diff + 1 - l1,
   2392                                     m->path + l2);
   2393 
   2394 			    schedule_rename(s, m->begin, new_path);
   2395 			}
   2396 			i++;
   2397 		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
   2398 		    c = fat_get(s, c);
   2399 		}
   2400 	    }
   2401 
   2402 	    free(old_path);
   2403 	    array_remove(&(s->commits), i);
   2404 	    continue;
   2405 	} else if (commit->action == ACTION_MKDIR) {
   2406 	    mapping_t* mapping;
   2407 	    int j, parent_path_len;
   2408 
   2409 #ifdef __MINGW32__
   2410             if (mkdir(commit->path))
   2411                 return -5;
   2412 #else
   2413             if (mkdir(commit->path, 0755))
   2414                 return -5;
   2415 #endif
   2416 
   2417 	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
   2418 		    commit->param.mkdir.cluster + 1);
   2419 	    if (mapping == NULL)
   2420 		return -6;
   2421 
   2422 	    mapping->mode = MODE_DIRECTORY;
   2423 	    mapping->read_only = 0;
   2424 	    mapping->path = commit->path;
   2425 	    j = s->directory.next;
   2426 	    assert(j);
   2427 	    insert_direntries(s, s->directory.next,
   2428 		    0x10 * s->sectors_per_cluster);
   2429 	    mapping->info.dir.first_dir_index = j;
   2430 
   2431 	    parent_path_len = strlen(commit->path)
   2432 		- strlen(get_basename(commit->path)) - 1;
   2433 	    for (j = 0; j < s->mapping.next; j++) {
   2434 		mapping_t* m = array_get(&(s->mapping), j);
   2435 		if (m->first_mapping_index < 0 && m != mapping &&
   2436 			!strncmp(m->path, mapping->path, parent_path_len) &&
   2437 			strlen(m->path) == parent_path_len)
   2438 		    break;
   2439 	    }
   2440 	    assert(j < s->mapping.next);
   2441 	    mapping->info.dir.parent_mapping_index = j;
   2442 
   2443 	    array_remove(&(s->commits), i);
   2444 	    continue;
   2445 	}
   2446 
   2447 	i++;
   2448     }
   2449     return 0;
   2450 }
   2451 
   2452 /*
   2453  * TODO: make sure that the short name is not matching *another* file
   2454  */
   2455 static int handle_commits(BDRVVVFATState* s)
   2456 {
   2457     int i, fail = 0;
   2458 
   2459     vvfat_close_current_file(s);
   2460 
   2461     for (i = 0; !fail && i < s->commits.next; i++) {
   2462 	commit_t* commit = array_get(&(s->commits), i);
   2463 	switch(commit->action) {
   2464 	case ACTION_RENAME: case ACTION_MKDIR:
   2465             abort();
   2466 	    fail = -2;
   2467 	    break;
   2468 	case ACTION_WRITEOUT: {
   2469 #ifndef NDEBUG
   2470             /* these variables are only used by assert() below */
   2471 	    direntry_t* entry = array_get(&(s->directory),
   2472 		    commit->param.writeout.dir_index);
   2473 	    uint32_t begin = begin_of_direntry(entry);
   2474 	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
   2475 #endif
   2476 
   2477 	    assert(mapping);
   2478 	    assert(mapping->begin == begin);
   2479 	    assert(commit->path == NULL);
   2480 
   2481 	    if (commit_one_file(s, commit->param.writeout.dir_index,
   2482 			commit->param.writeout.modified_offset))
   2483 		fail = -3;
   2484 
   2485 	    break;
   2486 	}
   2487 	case ACTION_NEW_FILE: {
   2488 	    int begin = commit->param.new_file.first_cluster;
   2489 	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
   2490 	    direntry_t* entry;
   2491 	    int i;
   2492 
   2493 	    /* find direntry */
   2494 	    for (i = 0; i < s->directory.next; i++) {
   2495 		entry = array_get(&(s->directory), i);
   2496 		if (is_file(entry) && begin_of_direntry(entry) == begin)
   2497 		    break;
   2498 	    }
   2499 
   2500 	    if (i >= s->directory.next) {
   2501 		fail = -6;
   2502 		continue;
   2503 	    }
   2504 
   2505 	    /* make sure there exists an initial mapping */
   2506 	    if (mapping && mapping->begin != begin) {
   2507 		mapping->end = begin;
   2508 		mapping = NULL;
   2509 	    }
   2510 	    if (mapping == NULL) {
   2511 		mapping = insert_mapping(s, begin, begin+1);
   2512 	    }
   2513 	    /* most members will be fixed in commit_mappings() */
   2514 	    assert(commit->path);
   2515 	    mapping->path = commit->path;
   2516 	    mapping->read_only = 0;
   2517 	    mapping->mode = MODE_NORMAL;
   2518 	    mapping->info.file.offset = 0;
   2519 
   2520 	    if (commit_one_file(s, i, 0))
   2521 		fail = -7;
   2522 
   2523 	    break;
   2524 	}
   2525 	default:
   2526             abort();
   2527 	}
   2528     }
   2529     if (i > 0 && array_remove_slice(&(s->commits), 0, i))
   2530 	return -1;
   2531     return fail;
   2532 }
   2533 
   2534 static int handle_deletes(BDRVVVFATState* s)
   2535 {
   2536     int i, deferred = 1, deleted = 1;
   2537 
   2538     /* delete files corresponding to mappings marked as deleted */
   2539     /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
   2540     while (deferred && deleted) {
   2541 	deferred = 0;
   2542 	deleted = 0;
   2543 
   2544 	for (i = 1; i < s->mapping.next; i++) {
   2545 	    mapping_t* mapping = array_get(&(s->mapping), i);
   2546 	    if (mapping->mode & MODE_DELETED) {
   2547 		direntry_t* entry = array_get(&(s->directory),
   2548 			mapping->dir_index);
   2549 
   2550 		if (is_free(entry)) {
   2551 		    /* remove file/directory */
   2552 		    if (mapping->mode & MODE_DIRECTORY) {
   2553 			int j, next_dir_index = s->directory.next,
   2554 			first_dir_index = mapping->info.dir.first_dir_index;
   2555 
   2556 			if (rmdir(mapping->path) < 0) {
   2557 			    if (errno == ENOTEMPTY) {
   2558 				deferred++;
   2559 				continue;
   2560 			    } else
   2561 				return -5;
   2562 			}
   2563 
   2564 			for (j = 1; j < s->mapping.next; j++) {
   2565 			    mapping_t* m = array_get(&(s->mapping), j);
   2566 			    if (m->mode & MODE_DIRECTORY &&
   2567 				    m->info.dir.first_dir_index >
   2568 				    first_dir_index &&
   2569 				    m->info.dir.first_dir_index <
   2570 				    next_dir_index)
   2571 				next_dir_index =
   2572 				    m->info.dir.first_dir_index;
   2573 			}
   2574 			remove_direntries(s, first_dir_index,
   2575 				next_dir_index - first_dir_index);
   2576 
   2577 			deleted++;
   2578 		    }
   2579 		} else {
   2580 		    if (unlink(mapping->path))
   2581 			return -4;
   2582 		    deleted++;
   2583 		}
   2584 		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
   2585 		remove_mapping(s, i);
   2586 	    }
   2587 	}
   2588     }
   2589 
   2590     return 0;
   2591 }
   2592 
   2593 /*
   2594  * synchronize mapping with new state:
   2595  *
   2596  * - copy FAT (with bdrv_read)
   2597  * - mark all filenames corresponding to mappings as deleted
   2598  * - recurse direntries from root (using bs->bdrv_read)
   2599  * - delete files corresponding to mappings marked as deleted
   2600  */
   2601 static int do_commit(BDRVVVFATState* s)
   2602 {
   2603     int ret = 0;
   2604 
   2605     /* the real meat are the commits. Nothing to do? Move along! */
   2606     if (s->commits.next == 0)
   2607 	return 0;
   2608 
   2609     vvfat_close_current_file(s);
   2610 
   2611     ret = handle_renames_and_mkdirs(s);
   2612     if (ret) {
   2613 	fprintf(stderr, "Error handling renames (%d)\n", ret);
   2614         abort();
   2615 	return ret;
   2616     }
   2617 
   2618     /* copy FAT (with bdrv_read) */
   2619     memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
   2620 
   2621     /* recurse direntries from root (using bs->bdrv_read) */
   2622     ret = commit_direntries(s, 0, -1);
   2623     if (ret) {
   2624 	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
   2625         abort();
   2626 	return ret;
   2627     }
   2628 
   2629     ret = handle_commits(s);
   2630     if (ret) {
   2631 	fprintf(stderr, "Error handling commits (%d)\n", ret);
   2632         abort();
   2633 	return ret;
   2634     }
   2635 
   2636     ret = handle_deletes(s);
   2637     if (ret) {
   2638 	fprintf(stderr, "Error deleting\n");
   2639         abort();
   2640 	return ret;
   2641     }
   2642 
   2643     s->qcow->drv->bdrv_make_empty(s->qcow);
   2644 
   2645     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
   2646 
   2647 DLOG(checkpoint());
   2648     return 0;
   2649 }
   2650 
   2651 static int try_commit(BDRVVVFATState* s)
   2652 {
   2653     vvfat_close_current_file(s);
   2654 DLOG(checkpoint());
   2655     if(!is_consistent(s))
   2656 	return -1;
   2657     return do_commit(s);
   2658 }
   2659 
   2660 static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
   2661                     const uint8_t *buf, int nb_sectors)
   2662 {
   2663     BDRVVVFATState *s = bs->opaque;
   2664     int i, ret;
   2665 
   2666 DLOG(checkpoint());
   2667 
   2668     vvfat_close_current_file(s);
   2669 
   2670     /*
   2671      * Some sanity checks:
   2672      * - do not allow writing to the boot sector
   2673      * - do not allow to write non-ASCII filenames
   2674      */
   2675 
   2676     if (sector_num < s->first_sectors_number)
   2677 	return -1;
   2678 
   2679     for (i = sector2cluster(s, sector_num);
   2680 	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
   2681 	mapping_t* mapping = find_mapping_for_cluster(s, i);
   2682 	if (mapping) {
   2683 	    if (mapping->read_only) {
   2684 		fprintf(stderr, "Tried to write to write-protected file %s\n",
   2685 			mapping->path);
   2686 		return -1;
   2687 	    }
   2688 
   2689 	    if (mapping->mode & MODE_DIRECTORY) {
   2690 		int begin = cluster2sector(s, i);
   2691 		int end = begin + s->sectors_per_cluster, k;
   2692 		int dir_index;
   2693 		const direntry_t* direntries;
   2694 		long_file_name lfn;
   2695 
   2696 		lfn_init(&lfn);
   2697 
   2698 		if (begin < sector_num)
   2699 		    begin = sector_num;
   2700 		if (end > sector_num + nb_sectors)
   2701 		    end = sector_num + nb_sectors;
   2702 		dir_index  = mapping->dir_index +
   2703 		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
   2704 		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
   2705 
   2706 		for (k = 0; k < (end - begin) * 0x10; k++) {
   2707 		    /* do not allow non-ASCII filenames */
   2708 		    if (parse_long_name(&lfn, direntries + k) < 0) {
   2709 			fprintf(stderr, "Warning: non-ASCII filename\n");
   2710 			return -1;
   2711 		    }
   2712 		    /* no access to the direntry of a read-only file */
   2713 		    else if (is_short_name(direntries+k) &&
   2714 			    (direntries[k].attributes & 1)) {
   2715 			if (memcmp(direntries + k,
   2716 				    array_get(&(s->directory), dir_index + k),
   2717 				    sizeof(direntry_t))) {
   2718 			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
   2719 			    return -1;
   2720 			}
   2721 		    }
   2722 		}
   2723 	    }
   2724 	    i = mapping->end;
   2725 	} else
   2726 	    i++;
   2727     }
   2728 
   2729     /*
   2730      * Use qcow backend. Commit later.
   2731      */
   2732 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
   2733     ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
   2734     if (ret < 0) {
   2735 	fprintf(stderr, "Error writing to qcow backend\n");
   2736 	return ret;
   2737     }
   2738 
   2739     for (i = sector2cluster(s, sector_num);
   2740 	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
   2741 	if (i >= 0)
   2742 	    s->used_clusters[i] |= USED_ALLOCATED;
   2743 
   2744 DLOG(checkpoint());
   2745     /* TODO: add timeout */
   2746     try_commit(s);
   2747 
   2748 DLOG(checkpoint());
   2749     return 0;
   2750 }
   2751 
   2752 static int vvfat_is_allocated(BlockDriverState *bs,
   2753 	int64_t sector_num, int nb_sectors, int* n)
   2754 {
   2755     BDRVVVFATState* s = bs->opaque;
   2756     *n = s->sector_count - sector_num;
   2757     if (*n > nb_sectors)
   2758 	*n = nb_sectors;
   2759     else if (*n < 0)
   2760 	return 0;
   2761     return 1;
   2762 }
   2763 
   2764 static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
   2765 	const uint8_t* buffer, int nb_sectors) {
   2766     BDRVVVFATState* s = bs->opaque;
   2767     return try_commit(s);
   2768 }
   2769 
   2770 static void write_target_close(BlockDriverState *bs) {
   2771     BDRVVVFATState* s = bs->opaque;
   2772     bdrv_delete(s->qcow);
   2773     free(s->qcow_filename);
   2774 }
   2775 
   2776 static BlockDriver vvfat_write_target = {
   2777     .format_name        = "vvfat_write_target",
   2778     .bdrv_write         = write_target_commit,
   2779     .bdrv_close         = write_target_close,
   2780 };
   2781 
   2782 static int enable_write_target(BDRVVVFATState *s)
   2783 {
   2784     BlockDriver *bdrv_qcow;
   2785     QEMUOptionParameter *options;
   2786     int size = sector2cluster(s, s->sector_count);
   2787     s->used_clusters = calloc(size, 1);
   2788 
   2789     array_init(&(s->commits), sizeof(commit_t));
   2790 
   2791     s->qcow_filename = qemu_malloc(1024);
   2792     get_tmp_filename(s->qcow_filename, 1024);
   2793 
   2794     bdrv_qcow = bdrv_find_format("qcow");
   2795     options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
   2796     set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
   2797     set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
   2798 
   2799     if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
   2800 	return -1;
   2801     s->qcow = bdrv_new("");
   2802     if (s->qcow == NULL ||
   2803         bdrv_open(s->qcow, s->qcow_filename, BDRV_O_RDWR, bdrv_qcow) < 0)
   2804     {
   2805 	return -1;
   2806     }
   2807 
   2808 #ifndef _WIN32
   2809     unlink(s->qcow_filename);
   2810 #endif
   2811 
   2812     s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
   2813     s->bs->backing_hd->drv = &vvfat_write_target;
   2814     s->bs->backing_hd->opaque = s;
   2815 
   2816     return 0;
   2817 }
   2818 
   2819 static void vvfat_close(BlockDriverState *bs)
   2820 {
   2821     BDRVVVFATState *s = bs->opaque;
   2822 
   2823     vvfat_close_current_file(s);
   2824     array_free(&(s->fat));
   2825     array_free(&(s->directory));
   2826     array_free(&(s->mapping));
   2827     if(s->cluster_buffer)
   2828         free(s->cluster_buffer);
   2829 }
   2830 
   2831 static BlockDriver bdrv_vvfat = {
   2832     .format_name	= "vvfat",
   2833     .instance_size	= sizeof(BDRVVVFATState),
   2834     .bdrv_file_open	= vvfat_open,
   2835     .bdrv_read		= vvfat_read,
   2836     .bdrv_write		= vvfat_write,
   2837     .bdrv_close		= vvfat_close,
   2838     .bdrv_is_allocated	= vvfat_is_allocated,
   2839     .protocol_name	= "fat",
   2840 };
   2841 
   2842 static void bdrv_vvfat_init(void)
   2843 {
   2844     bdrv_register(&bdrv_vvfat);
   2845 }
   2846 
   2847 block_init(bdrv_vvfat_init);
   2848 
   2849 #ifdef DEBUG
   2850 static void checkpoint(void) {
   2851     assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
   2852     check1(vvv);
   2853     check2(vvv);
   2854     assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
   2855 #if 0
   2856     if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
   2857 	fprintf(stderr, "Nonono!\n");
   2858     mapping_t* mapping;
   2859     direntry_t* direntry;
   2860     assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
   2861     assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
   2862     if (vvv->mapping.next<47)
   2863 	return;
   2864     assert((mapping = array_get(&(vvv->mapping), 47)));
   2865     assert(mapping->dir_index < vvv->directory.next);
   2866     direntry = array_get(&(vvv->directory), mapping->dir_index);
   2867     assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
   2868 #endif
   2869     return;
   2870     /* avoid compiler warnings: */
   2871     hexdump(NULL, 100);
   2872     remove_mapping(vvv, 0);
   2873     print_mapping(NULL);
   2874     print_direntry(NULL);
   2875 }
   2876 #endif
   2877