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