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