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