1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
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:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48: #ifdef DEBUG
49:
50: #define DLOG(a) a
51:
52: #undef stderr
53: #define stderr STDERR
54: FILE* stderr = NULL;
55:
56: static void checkpoint();
57:
58: #ifdef __MINGW32__
59: void nonono(const char* file, int line, const char* msg) {
60: fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
61: exit(-5);
62: }
63: #undef assert
64: #define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
65: #endif
66:
67: #else
68:
69: #define DLOG(a)
70:
71: #endif
72:
73:
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:
95: static inline void* array_get(array_t* array,unsigned int index) {
96: assert(index >= 0);
97: assert(index < array->next);
98: return array->pointer + index * array->item_size;
99: }
100:
101: static inline int array_ensure_allocated(array_t* array, int index)
102: {
103: if((index + 1) * array->item_size > array->size) {
104: int new_size = (index + 32) * array->item_size;
105: array->pointer = realloc(array->pointer, new_size);
106: if (!array->pointer)
107: return -1;
108: array->size = new_size;
109: array->next = index + 1;
110: }
111:
112: return 0;
113: }
114:
115: static inline void* array_get_next(array_t* array) {
116: unsigned int next = array->next;
117: void* result;
118:
119: if (array_ensure_allocated(array, next) < 0)
120: return NULL;
121:
122: array->next = next + 1;
123: result = array_get(array, next);
124:
125: return result;
126: }
127:
128: static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
129: if((array->next+count)*array->item_size>array->size) {
130: int increment=count*array->item_size;
131: array->pointer=realloc(array->pointer,array->size+increment);
132: if(!array->pointer)
133: return 0;
134: array->size+=increment;
135: }
136: memmove(array->pointer+(index+count)*array->item_size,
137: array->pointer+index*array->item_size,
138: (array->next-index)*array->item_size);
139: array->next+=count;
140: return array->pointer+index*array->item_size;
141: }
142:
143:
144:
145: static inline int array_roll(array_t* array,int index_to,int index_from,int count)
146: {
147: char* buf;
148: char* from;
149: char* to;
150: int is;
151:
152: if(!array ||
153: index_to<0 || index_to>=array->next ||
154: index_from<0 || index_from>=array->next)
155: return -1;
156:
157: if(index_to==index_from)
158: return 0;
159:
160: is=array->item_size;
161: from=array->pointer+index_from*is;
162: to=array->pointer+index_to*is;
163: buf=malloc(is*count);
164: memcpy(buf,from,is*count);
165:
166: if(index_to<index_from)
167: memmove(to+is*count,to,from-to);
168: else
169: memmove(from,from+is*count,to-from);
170:
171: memcpy(to,buf,is*count);
172:
173: free(buf);
174:
175: return 0;
176: }
177:
178: static inline int array_remove_slice(array_t* array,int index, int count)
179: {
180: assert(index >=0);
181: assert(count > 0);
182: assert(index + count <= array->next);
183: if(array_roll(array,array->next-1,index,count))
184: return -1;
185: array->next -= count;
186: return 0;
187: }
188:
189: static int array_remove(array_t* array,int index)
190: {
191: return array_remove_slice(array, index, 1);
192: }
193:
194:
195: static int array_index(array_t* array, void* pointer)
196: {
197: size_t offset = (char*)pointer - array->pointer;
198: assert(offset >= 0);
199: assert((offset % array->item_size) == 0);
200: assert(offset/array->item_size < array->next);
201: return offset/array->item_size;
202: }
203:
204:
205:
206:
207: typedef struct bootsector_t {
208: uint8_t jump[3];
209: uint8_t name[8];
210: uint16_t sector_size;
211: uint8_t sectors_per_cluster;
212: uint16_t reserved_sectors;
213: uint8_t number_of_fats;
214: uint16_t root_entries;
215: uint16_t total_sectors16;
216: uint8_t media_type;
217: uint16_t sectors_per_fat;
218: uint16_t sectors_per_track;
219: uint16_t number_of_heads;
220: uint32_t hidden_sectors;
221: uint32_t total_sectors;
222: union {
223: struct {
224: uint8_t drive_number;
225: uint8_t current_head;
226: uint8_t signature;
227: uint32_t id;
228: uint8_t volume_label[11];
229: } __attribute__((packed)) fat16;
230: struct {
231: uint32_t sectors_per_fat;
232: uint16_t flags;
233: uint8_t major,minor;
234: uint32_t first_cluster_of_root_directory;
235: uint16_t info_sector;
236: uint16_t backup_boot_sector;
237: uint16_t ignored;
238: } __attribute__((packed)) fat32;
239: } u;
240: uint8_t fat_type[8];
241: uint8_t ignored[0x1c0];
242: uint8_t magic[2];
243: } __attribute__((packed)) bootsector_t;
244:
245: typedef struct {
246: uint8_t head;
247: uint8_t sector;
248: uint8_t cylinder;
249: } mbr_chs_t;
250:
251: typedef struct partition_t {
252: uint8_t attributes;
253: mbr_chs_t start_CHS;
254: uint8_t fs_type;
255: mbr_chs_t end_CHS;
256: uint32_t start_sector_long;
257: uint32_t length_sector_long;
258: } __attribute__((packed)) partition_t;
259:
260: typedef struct mbr_t {
261: uint8_t ignored[0x1b8];
262: uint32_t nt_id;
263: uint8_t ignored2[2];
264: partition_t partition[4];
265: uint8_t magic[2];
266: } __attribute__((packed)) mbr_t;
267:
268: typedef struct direntry_t {
269: uint8_t name[8];
270: uint8_t extension[3];
271: uint8_t attributes;
272: uint8_t reserved[2];
273: uint16_t ctime;
274: uint16_t cdate;
275: uint16_t adate;
276: uint16_t begin_hi;
277: uint16_t mtime;
278: uint16_t mdate;
279: uint16_t begin;
280: uint32_t size;
281: } __attribute__((packed)) direntry_t;
282:
283:
284:
285: typedef struct mapping_t {
286:
287: uint32_t begin,end;
288:
289: unsigned int dir_index;
290:
291: int first_mapping_index;
292: union {
293:
294:
295:
296:
297:
298: struct {
299: uint32_t offset;
300: } file;
301: struct {
302: int parent_mapping_index;
303: int first_dir_index;
304: } dir;
305: } info;
306:
307: char* path;
308:
309: enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
310: MODE_DIRECTORY = 4, MODE_FAKED = 8,
311: MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
312: int read_only;
313: } mapping_t;
314:
315: #ifdef DEBUG
316: static void print_direntry(const struct direntry_t*);
317: static void print_mapping(const struct mapping_t* mapping);
318: #endif
319:
320:
321:
322: typedef struct BDRVVVFATState {
323: BlockDriverState* bs;
324: unsigned int first_sectors_number;
325: unsigned char first_sectors[0x40*0x200];
326:
327: int fat_type;
328: array_t fat,directory,mapping;
329:
330: unsigned int cluster_size;
331: unsigned int sectors_per_cluster;
332: unsigned int sectors_per_fat;
333: unsigned int sectors_of_root_directory;
334: uint32_t last_cluster_of_root_directory;
335: unsigned int faked_sectors;
336: uint32_t sector_count;
337: uint32_t cluster_count;
338: uint32_t max_fat_value;
339:
340: int current_fd;
341: mapping_t* current_mapping;
342: unsigned char* cluster;
343: unsigned char* cluster_buffer;
344: unsigned int current_cluster;
345:
346:
347: BlockDriverState* write_target;
348: char* qcow_filename;
349: BlockDriverState* qcow;
350: void* fat2;
351: char* used_clusters;
352: array_t commits;
353: const char* path;
354: int downcase_short_names;
355: } BDRVVVFATState;
356:
357:
358:
359:
360:
361: static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
362: int head,sector;
363: sector = spos % (bs->secs); spos/= bs->secs;
364: head = spos % (bs->heads); spos/= bs->heads;
365: if(spos >= bs->cyls){
366:
367:
368:
369: chs->head = 0xFF;
370: chs->sector = 0xFF;
371: chs->cylinder = 0xFF;
372: return 1;
373: }
374: chs->head = (uint8_t)head;
375: chs->sector = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
376: chs->cylinder = (uint8_t)spos;
377: return 0;
378: }
379:
380: static void init_mbr(BDRVVVFATState* s)
381: {
382:
383: mbr_t* real_mbr=(mbr_t*)s->first_sectors;
384: partition_t* partition=&(real_mbr->partition[0]);
385: int lba;
386:
387: memset(s->first_sectors,0,512);
388:
389:
390: real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
391:
392: partition->attributes=0x80;
393:
394:
395: lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
396: lba|= sector2CHS(s->bs, &partition->end_CHS, s->sector_count);
397:
398:
399: partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
400: partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
401:
402:
403:
404:
405: partition->fs_type= s->fat_type==12 ? 0x1:
406: s->fat_type==16 ? (lba?0xe:0x06):
407: (lba?0xc:0x0b);
408:
409: real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
410: }
411:
412:
413:
414:
415: static inline int short2long_name(char* dest,const char* src)
416: {
417: int i;
418: int len;
419: for(i=0;i<129 && src[i];i++) {
420: dest[2*i]=src[i];
421: dest[2*i+1]=0;
422: }
423: len=2*i;
424: dest[2*i]=dest[2*i+1]=0;
425: for(i=2*i+2;(i%26);i++)
426: dest[i]=0xff;
427: return len;
428: }
429:
430: static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
431: {
432: char buffer[258];
433: int length=short2long_name(buffer,filename),
434: number_of_entries=(length+25)/26,i;
435: direntry_t* entry;
436:
437: for(i=0;i<number_of_entries;i++) {
438: entry=array_get_next(&(s->directory));
439: entry->attributes=0xf;
440: entry->reserved[0]=0;
441: entry->begin=0;
442: entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
443: }
444: for(i=0;i<26*number_of_entries;i++) {
445: int offset=(i%26);
446: if(offset<10) offset=1+offset;
447: else if(offset<22) offset=14+offset-10;
448: else offset=28+offset-22;
449: entry=array_get(&(s->directory),s->directory.next-1-(i/26));
450: entry->name[offset]=buffer[i];
451: }
452: return array_get(&(s->directory),s->directory.next-number_of_entries);
453: }
454:
455: static char is_free(const direntry_t* direntry)
456: {
457:
458: return direntry->attributes == 0 || direntry->name[0]==0xe5;
459: }
460:
461: static char is_volume_label(const direntry_t* direntry)
462: {
463: return direntry->attributes == 0x28;
464: }
465:
466: static char is_long_name(const direntry_t* direntry)
467: {
468: return direntry->attributes == 0xf;
469: }
470:
471: static char is_short_name(const direntry_t* direntry)
472: {
473: return !is_volume_label(direntry) && !is_long_name(direntry)
474: && !is_free(direntry);
475: }
476:
477: static char is_directory(const direntry_t* direntry)
478: {
479: return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
480: }
481:
482: static inline char is_dot(const direntry_t* direntry)
483: {
484: return is_short_name(direntry) && direntry->name[0] == '.';
485: }
486:
487: static char is_file(const direntry_t* direntry)
488: {
489: return is_short_name(direntry) && !is_directory(direntry);
490: }
491:
492: static inline uint32_t begin_of_direntry(const direntry_t* direntry)
493: {
494: return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
495: }
496:
497: static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
498: {
499: return le32_to_cpu(direntry->size);
500: }
501:
502: static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
503: {
504: direntry->begin = cpu_to_le16(begin & 0xffff);
505: direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
506: }
507:
508:
509:
510: static inline uint8_t fat_chksum(const direntry_t* entry)
511: {
512: uint8_t chksum=0;
513: int i;
514:
515: for(i=0;i<11;i++)
516: chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0))
517: +(unsigned char)entry->name[i];
518:
519: return chksum;
520: }
521:
522:
523: static uint16_t fat_datetime(time_t time,int return_time) {
524: struct tm* t;
525: #ifdef _WIN32
526: t=localtime(&time);
527: #else
528: struct tm t1;
529: t=&t1;
530: localtime_r(&time,t);
531: #endif
532: if(return_time)
533: return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
534: return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
535: }
536:
537: static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
538: {
539: if(s->fat_type==32) {
540: uint32_t* entry=array_get(&(s->fat),cluster);
541: *entry=cpu_to_le32(value);
542: } else if(s->fat_type==16) {
543: uint16_t* entry=array_get(&(s->fat),cluster);
544: *entry=cpu_to_le16(value&0xffff);
545: } else {
546: int offset = (cluster*3/2);
547: unsigned char* p = array_get(&(s->fat), offset);
548: switch (cluster&1) {
549: case 0:
550: p[0] = value&0xff;
551: p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
552: break;
553: