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