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