From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487834912960.5358797108265; Mon, 22 May 2017 14:17:14 -0700 (PDT) Received: from localhost ([::1]:44940 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuhV-00033q-GN for importer@patchew.org; Mon, 22 May 2017 17:17:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37307) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuco-0007dU-R4 for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCucn-00007l-Mo for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:22 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36672) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuci-0008VT-TZ; Mon, 22 May 2017 17:12:17 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 079512003C1; Mon, 22 May 2017 23:12:13 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:53 +0200 Message-Id: <20170522211205.14265-2-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" - bs->total_sectors is the number of sectors of the whole disk - s->sector_count is the number of sectors of the FAT partition This fixes the following assert in qemu-img map: qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed. This also fixes an infinite loop in qemu-img convert. Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0 Fixes: https://bugs.launchpad.net/qemu/+bug/1599539 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 9c82371360..df24091bf6 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2969,8 +2969,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offse= t, uint64_t bytes, static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file) { - BDRVVVFATState* s =3D bs->opaque; - *n =3D s->sector_count - sector_num; + *n =3D bs->total_sectors - sector_num; if (*n > nb_sectors) { *n =3D nb_sectors; } else if (*n < 0) { --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495488315436795.601291801184; Mon, 22 May 2017 14:25:15 -0700 (PDT) Received: from localhost ([::1]:44994 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCupF-0000nF-IL for importer@patchew.org; Mon, 22 May 2017 17:25:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37488) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCudA-00083I-7H for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCud2-0000GX-IH for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:44 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36763) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuci-0008Vh-TT; Mon, 22 May 2017 17:12:17 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 72D25200379; Mon, 22 May 2017 23:12:13 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:54 +0200 Message-Id: <20170522211205.14265-3-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This was a complete mess. On 2299 indented lines: - 1329 were with spaces only - 617 with tabulations only - 353 with spaces and tabulations Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 2054 ++++++++++++++++++++++++++++-------------------------= ---- 1 file changed, 1027 insertions(+), 1027 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index df24091bf6..d3afb731b6 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -101,12 +101,12 @@ static inline void* array_get(array_t* array,unsigned= int index) { static inline int array_ensure_allocated(array_t* array, int index) { if((index + 1) * array->item_size > array->size) { - int new_size =3D (index + 32) * array->item_size; - array->pointer =3D g_realloc(array->pointer, new_size); - if (!array->pointer) - return -1; - array->size =3D new_size; - array->next =3D index + 1; + int new_size =3D (index + 32) * array->item_size; + array->pointer =3D g_realloc(array->pointer, new_size); + if (!array->pointer) + return -1; + array->size =3D new_size; + array->next =3D index + 1; } =20 return 0; @@ -116,7 +116,7 @@ static inline void* array_get_next(array_t* array) { unsigned int next =3D array->next; =20 if (array_ensure_allocated(array, next) < 0) - return NULL; + return NULL; =20 array->next =3D next + 1; return array_get(array, next); @@ -124,15 +124,15 @@ static inline void* array_get_next(array_t* array) { =20 static inline void* array_insert(array_t* array,unsigned int index,unsigne= d int count) { if((array->next+count)*array->item_size>array->size) { - int increment=3Dcount*array->item_size; - array->pointer=3Dg_realloc(array->pointer,array->size+increment); - if(!array->pointer) + int increment=3Dcount*array->item_size; + array->pointer=3Dg_realloc(array->pointer,array->size+increment); + if(!array->pointer) return NULL; - array->size+=3Dincrement; + array->size+=3Dincrement; } memmove(array->pointer+(index+count)*array->item_size, - array->pointer+index*array->item_size, - (array->next-index)*array->item_size); + array->pointer+index*array->item_size, + (array->next-index)*array->item_size); array->next+=3Dcount; return array->pointer+index*array->item_size; } @@ -147,12 +147,12 @@ static inline int array_roll(array_t* array,int index= _to,int index_from,int coun int is; =20 if(!array || - index_to<0 || index_to>=3Darray->next || - index_from<0 || index_from>=3Darray->next) - return -1; + index_to<0 || index_to>=3Darray->next || + index_from<0 || index_from>=3Darray->next) + return -1; =20 if(index_to=3D=3Dindex_from) - return 0; + return 0; =20 is=3Darray->item_size; from=3Darray->pointer+index_from*is; @@ -161,9 +161,9 @@ static inline int array_roll(array_t* array,int index_t= o,int index_from,int coun memcpy(buf,from,is*count); =20 if(index_to 0); assert(index + count <=3D array->next); if(array_roll(array,array->next-1,index,count)) - return -1; + return -1; array->next -=3D count; return 0; } @@ -217,21 +217,21 @@ typedef struct bootsector_t { uint32_t total_sectors; union { struct { - uint8_t drive_number; - uint8_t current_head; - uint8_t signature; - uint32_t id; - uint8_t volume_label[11]; - } QEMU_PACKED fat16; - struct { - uint32_t sectors_per_fat; - uint16_t flags; - uint8_t major,minor; - uint32_t first_cluster_of_root_directory; - uint16_t info_sector; - uint16_t backup_boot_sector; - uint16_t ignored; - } QEMU_PACKED fat32; + uint8_t drive_number; + uint8_t current_head; + uint8_t signature; + uint32_t id; + uint8_t volume_label[11]; + } QEMU_PACKED fat16; + struct { + uint32_t sectors_per_fat; + uint16_t flags; + uint8_t major,minor; + uint32_t first_cluster_of_root_directory; + uint16_t info_sector; + uint16_t backup_boot_sector; + uint16_t ignored; + } QEMU_PACKED fat32; } u; uint8_t fat_type[8]; uint8_t ignored[0x1c0]; @@ -285,25 +285,25 @@ typedef struct mapping_t { /* the clusters of a file may be in any order; this points to the firs= t */ int first_mapping_index; union { - /* offset is - * - the offset in the file (in clusters) for a file, or - * - the next cluster of the directory for a directory, and - * - the address of the buffer for a faked entry - */ - struct { - uint32_t offset; - } file; - struct { - int parent_mapping_index; - int first_dir_index; - } dir; + /* offset is + * - the offset in the file (in clusters) for a file, or + * - the next cluster of the directory for a directory, and + * - the address of the buffer for a faked entry + */ + struct { + uint32_t offset; + } file; + struct { + int parent_mapping_index; + int first_dir_index; + } dir; } info; /* path contains the full path, i.e. it always starts with s->path */ char* path; =20 enum { MODE_UNDEFINED =3D 0, MODE_NORMAL =3D 1, MODE_MODIFIED =3D 2, - MODE_DIRECTORY =3D 4, MODE_FAKED =3D 8, - MODE_DELETED =3D 16, MODE_RENAMED =3D 32 } mode; + MODE_DIRECTORY =3D 4, MODE_FAKED =3D 8, + MODE_DELETED =3D 16, MODE_RENAMED =3D 32 } mode; int read_only; } mapping_t; =20 @@ -420,12 +420,12 @@ static inline int short2long_name(char* dest,const ch= ar* src) int len; for(i=3D0;i<129 && src[i];i++) { dest[2*i]=3Dsrc[i]; - dest[2*i+1]=3D0; + dest[2*i+1]=3D0; } len=3D2*i; dest[2*i]=3Ddest[2*i+1]=3D0; for(i=3D2*i+2;(i%26);i++) - dest[i]=3D0xff; + dest[i]=3D0xff; return len; } =20 @@ -437,19 +437,19 @@ static inline direntry_t* create_long_filename(BDRVVV= FATState* s,const char* fil direntry_t* entry; =20 for(i=3D0;idirectory)); - entry->attributes=3D0xf; - entry->reserved[0]=3D0; - entry->begin=3D0; - entry->name[0]=3D(number_of_entries-i)|(i=3D=3D0?0x40:0); + entry=3Darray_get_next(&(s->directory)); + entry->attributes=3D0xf; + entry->reserved[0]=3D0; + entry->begin=3D0; + entry->name[0]=3D(number_of_entries-i)|(i=3D=3D0?0x40:0); } for(i=3D0;i<26*number_of_entries;i++) { - int offset=3D(i%26); - if(offset<10) offset=3D1+offset; - else if(offset<22) offset=3D14+offset-10; - else offset=3D28+offset-22; - entry=3Darray_get(&(s->directory),s->directory.next-1-(i/26)); - entry->name[offset]=3Dbuffer[i]; + int offset=3D(i%26); + if(offset<10) offset=3D1+offset; + else if(offset<22) offset=3D14+offset-10; + else offset=3D28+offset-22; + entry=3Darray_get(&(s->directory),s->directory.next-1-(i/26)); + entry->name[offset]=3Dbuffer[i]; } return array_get(&(s->directory),s->directory.next-number_of_entries); } @@ -472,7 +472,7 @@ static char is_long_name(const direntry_t* direntry) static char is_short_name(const direntry_t* direntry) { return !is_volume_label(direntry) && !is_long_name(direntry) - && !is_free(direntry); + && !is_free(direntry); } =20 static char is_directory(const direntry_t* direntry) @@ -528,73 +528,73 @@ static uint16_t fat_datetime(time_t time,int return_t= ime) { t =3D &t1; localtime_r(&time,t); if(return_time) - return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11)); + return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11)); return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9= )); } =20 static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t= value) { if(s->fat_type=3D=3D32) { - uint32_t* entry=3Darray_get(&(s->fat),cluster); - *entry=3Dcpu_to_le32(value); + uint32_t* entry=3Darray_get(&(s->fat),cluster); + *entry=3Dcpu_to_le32(value); } else if(s->fat_type=3D=3D16) { - uint16_t* entry=3Darray_get(&(s->fat),cluster); - *entry=3Dcpu_to_le16(value&0xffff); + uint16_t* entry=3Darray_get(&(s->fat),cluster); + *entry=3Dcpu_to_le16(value&0xffff); } else { - int offset =3D (cluster*3/2); - unsigned char* p =3D array_get(&(s->fat), offset); + int offset =3D (cluster*3/2); + unsigned char* p =3D array_get(&(s->fat), offset); switch (cluster&1) { - case 0: - p[0] =3D value&0xff; - p[1] =3D (p[1]&0xf0) | ((value>>8)&0xf); - break; - case 1: - p[0] =3D (p[0]&0xf) | ((value&0xf)<<4); - p[1] =3D (value>>4); - break; - } + case 0: + p[0] =3D value&0xff; + p[1] =3D (p[1]&0xf0) | ((value>>8)&0xf); + break; + case 1: + p[0] =3D (p[0]&0xf) | ((value&0xf)<<4); + p[1] =3D (value>>4); + break; + } } } =20 static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster) { if(s->fat_type=3D=3D32) { - uint32_t* entry=3Darray_get(&(s->fat),cluster); - return le32_to_cpu(*entry); + uint32_t* entry=3Darray_get(&(s->fat),cluster); + return le32_to_cpu(*entry); } else if(s->fat_type=3D=3D16) { - uint16_t* entry=3Darray_get(&(s->fat),cluster); - return le16_to_cpu(*entry); + uint16_t* entry=3Darray_get(&(s->fat),cluster); + return le16_to_cpu(*entry); } else { - const uint8_t* x=3D(uint8_t*)(s->fat.pointer)+cluster*3/2; - return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff; + const uint8_t* x=3D(uint8_t*)(s->fat.pointer)+cluster*3/2; + return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff; } } =20 static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry) { if(fat_entry>s->max_fat_value-8) - return -1; + return -1; return 0; } =20 static inline void init_fat(BDRVVVFATState* s) { if (s->fat_type =3D=3D 12) { - array_init(&(s->fat),1); - array_ensure_allocated(&(s->fat), - s->sectors_per_fat * 0x200 * 3 / 2 - 1); + array_init(&(s->fat),1); + array_ensure_allocated(&(s->fat), + s->sectors_per_fat * 0x200 * 3 / 2 - 1); } else { - array_init(&(s->fat),(s->fat_type=3D=3D32?4:2)); - array_ensure_allocated(&(s->fat), - s->sectors_per_fat * 0x200 / s->fat.item_size - 1); + array_init(&(s->fat),(s->fat_type=3D=3D32?4:2)); + array_ensure_allocated(&(s->fat), + s->sectors_per_fat * 0x200 / s->fat.item_size - 1); } memset(s->fat.pointer,0,s->fat.size); =20 switch(s->fat_type) { - case 12: s->max_fat_value=3D0xfff; break; - case 16: s->max_fat_value=3D0xffff; break; - case 32: s->max_fat_value=3D0x0fffffff; break; - default: s->max_fat_value=3D0; /* error... */ + case 12: s->max_fat_value=3D0xfff; break; + case 16: s->max_fat_value=3D0xffff; break; + case 32: s->max_fat_value=3D0x0fffffff; break; + default: s->max_fat_value=3D0; /* error... */ } =20 } @@ -602,17 +602,17 @@ static inline void init_fat(BDRVVVFATState* s) /* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */ /* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, - unsigned int directory_start, const char* filename, int is_dot) + unsigned int directory_start, const char* filename, int is_dot) { int i,j,long_index=3Ds->directory.next; direntry_t* entry =3D NULL; direntry_t* entry_long =3D NULL; =20 if(is_dot) { - entry=3Darray_get_next(&(s->directory)); + entry=3Darray_get_next(&(s->directory)); memset(entry->name, 0x20, sizeof(entry->name)); - memcpy(entry->name,filename,strlen(filename)); - return entry; + memcpy(entry->name,filename,strlen(filename)); + return entry; } =20 entry_long=3Dcreate_long_filename(s,filename); @@ -620,9 +620,9 @@ static inline direntry_t* create_short_and_long_name(BD= RVVVFATState* s, i =3D strlen(filename); for(j =3D i - 1; j>0 && filename[j]!=3D'.';j--); if (j > 0) - i =3D (j > 8 ? 8 : j); + i =3D (j > 8 ? 8 : j); else if (i > 8) - i =3D 8; + i =3D 8; =20 entry=3Darray_get_next(&(s->directory)); memset(entry->name, 0x20, sizeof(entry->name)); @@ -636,53 +636,53 @@ static inline direntry_t* create_short_and_long_name(= BDRVVVFATState* s, =20 /* upcase & remove unwanted characters */ for(i=3D10;i>=3D0;i--) { - if(i=3D=3D10 || i=3D=3D7) for(;i>0 && entry->name[i]=3D=3D' ';i--); - if(entry->name[i]<=3D' ' || entry->name[i]>0x7f - || strchr(".*?<>|\":/\\[];,+=3D'",entry->name[i])) - entry->name[i]=3D'_'; + if(i=3D=3D10 || i=3D=3D7) for(;i>0 && entry->name[i]=3D=3D' ';i--); + if(entry->name[i]<=3D' ' || entry->name[i]>0x7f + || strchr(".*?<>|\":/\\[];,+=3D'",entry->name[i])) + entry->name[i]=3D'_'; else if(entry->name[i]>=3D'a' && entry->name[i]<=3D'z') entry->name[i]+=3D'A'-'a'; } =20 /* mangle duplicates */ while(1) { - direntry_t* entry1=3Darray_get(&(s->directory),directory_start); - int j; - - for(;entry1name,entry->name,11)) - break; /* found dupe */ - if(entry1=3D=3Dentry) /* no dupe found */ - break; - - /* use all 8 characters of name */ - if(entry->name[7]=3D=3D' ') { - int j; - for(j=3D6;j>0 && entry->name[j]=3D=3D' ';j--) - entry->name[j]=3D'~'; - } - - /* increment number */ - for(j=3D7;j>0 && entry->name[j]=3D=3D'9';j--) - entry->name[j]=3D'0'; - if(j>0) { - if(entry->name[j]<'0' || entry->name[j]>'9') - entry->name[j]=3D'0'; - else - entry->name[j]++; - } + direntry_t* entry1=3Darray_get(&(s->directory),directory_start); + int j; + + for(;entry1name,entry->name,1= 1)) + break; /* found dupe */ + if(entry1=3D=3Dentry) /* no dupe found */ + break; + + /* use all 8 characters of name */ + if(entry->name[7]=3D=3D' ') { + int j; + for(j=3D6;j>0 && entry->name[j]=3D=3D' ';j--) + entry->name[j]=3D'~'; + } + + /* increment number */ + for(j=3D7;j>0 && entry->name[j]=3D=3D'9';j--) + entry->name[j]=3D'0'; + if(j>0) { + if(entry->name[j]<'0' || entry->name[j]>'9') + entry->name[j]=3D'0'; + else + entry->name[j]++; + } } =20 /* calculate checksum; propagate to long name */ if(entry_long) { uint8_t chksum=3Dfat_chksum(entry); =20 - /* calculate anew, because realloc could have taken place */ - entry_long=3Darray_get(&(s->directory),long_index); - while(entry_longreserved[1]=3Dchksum; - entry_long++; - } + /* calculate anew, because realloc could have taken place */ + entry_long=3Darray_get(&(s->directory),long_index); + while(entry_longreserved[1]=3Dchksum; + entry_long++; + } } =20 return entry; @@ -709,80 +709,80 @@ static int read_directory(BDRVVVFATState* s, int mapp= ing_index) assert(mapping->mode & MODE_DIRECTORY); =20 if(!dir) { - mapping->end =3D mapping->begin; - return -1; + mapping->end =3D mapping->begin; + return -1; } =20 i =3D mapping->info.dir.first_dir_index =3D - first_cluster =3D=3D 0 ? 0 : s->directory.next; + first_cluster =3D=3D 0 ? 0 : s->directory.next; =20 /* actually read the directory, and allocate the mappings */ while((entry=3Dreaddir(dir))) { - unsigned int length=3Dstrlen(dirname)+2+strlen(entry->d_name); + unsigned int length=3Dstrlen(dirname)+2+strlen(entry->d_name); char* buffer; - direntry_t* direntry; + direntry_t* direntry; struct stat st; - int is_dot=3D!strcmp(entry->d_name,"."); - int is_dotdot=3D!strcmp(entry->d_name,".."); + int is_dot=3D!strcmp(entry->d_name,"."); + int is_dotdot=3D!strcmp(entry->d_name,".."); =20 - if(first_cluster =3D=3D 0 && (is_dotdot || is_dot)) - continue; + if(first_cluster =3D=3D 0 && (is_dotdot || is_dot)) + continue; =20 - buffer =3D g_malloc(length); - snprintf(buffer,length,"%s/%s",dirname,entry->d_name); + buffer =3D g_malloc(length); + snprintf(buffer,length,"%s/%s",dirname,entry->d_name); =20 - if(stat(buffer,&st)<0) { + if(stat(buffer,&st)<0) { g_free(buffer); continue; - } - - /* create directory entry for this file */ - direntry=3Dcreate_short_and_long_name(s, i, entry->d_name, - is_dot || is_dotdot); - direntry->attributes=3D(S_ISDIR(st.st_mode)?0x10:0x20); - direntry->reserved[0]=3Ddirentry->reserved[1]=3D0; - direntry->ctime=3Dfat_datetime(st.st_ctime,1); - direntry->cdate=3Dfat_datetime(st.st_ctime,0); - direntry->adate=3Dfat_datetime(st.st_atime,0); - direntry->begin_hi=3D0; - direntry->mtime=3Dfat_datetime(st.st_mtime,1); - direntry->mdate=3Dfat_datetime(st.st_mtime,0); - if(is_dotdot) - set_begin_of_direntry(direntry, first_cluster_of_parent); - else if(is_dot) - set_begin_of_direntry(direntry, first_cluster); - else - direntry->begin=3D0; /* do that later */ + } + + /* create directory entry for this file */ + direntry=3Dcreate_short_and_long_name(s, i, entry->d_name, + is_dot || is_dotdot); + direntry->attributes=3D(S_ISDIR(st.st_mode)?0x10:0x20); + direntry->reserved[0]=3Ddirentry->reserved[1]=3D0; + direntry->ctime=3Dfat_datetime(st.st_ctime,1); + direntry->cdate=3Dfat_datetime(st.st_ctime,0); + direntry->adate=3Dfat_datetime(st.st_atime,0); + direntry->begin_hi=3D0; + direntry->mtime=3Dfat_datetime(st.st_mtime,1); + direntry->mdate=3Dfat_datetime(st.st_mtime,0); + if(is_dotdot) + set_begin_of_direntry(direntry, first_cluster_of_parent); + else if(is_dot) + set_begin_of_direntry(direntry, first_cluster); + else + direntry->begin=3D0; /* do that later */ if (st.st_size > 0x7fffffff) { - fprintf(stderr, "File %s is larger than 2GB\n", buffer); + fprintf(stderr, "File %s is larger than 2GB\n", buffer); g_free(buffer); closedir(dir); - return -2; + return -2; } - direntry->size=3Dcpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size); - - /* create mapping for this file */ - if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) { - s->current_mapping =3D array_get_next(&(s->mapping)); - s->current_mapping->begin=3D0; - s->current_mapping->end=3Dst.st_size; - /* - * we get the direntry of the most recent direntry, which - * contains the short name and all the relevant information. - */ - s->current_mapping->dir_index=3Ds->directory.next-1; - s->current_mapping->first_mapping_index =3D -1; - if (S_ISDIR(st.st_mode)) { - s->current_mapping->mode =3D MODE_DIRECTORY; - s->current_mapping->info.dir.parent_mapping_index =3D - mapping_index; - } else { - s->current_mapping->mode =3D MODE_UNDEFINED; - s->current_mapping->info.file.offset =3D 0; - } - s->current_mapping->path=3Dbuffer; - s->current_mapping->read_only =3D - (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) =3D=3D 0; + direntry->size=3Dcpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size); + + /* create mapping for this file */ + if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) { + s->current_mapping =3D array_get_next(&(s->mapping)); + s->current_mapping->begin=3D0; + s->current_mapping->end=3Dst.st_size; + /* + * we get the direntry of the most recent direntry, which + * contains the short name and all the relevant information. + */ + s->current_mapping->dir_index=3Ds->directory.next-1; + s->current_mapping->first_mapping_index =3D -1; + if (S_ISDIR(st.st_mode)) { + s->current_mapping->mode =3D MODE_DIRECTORY; + s->current_mapping->info.dir.parent_mapping_index =3D + mapping_index; + } else { + s->current_mapping->mode =3D MODE_UNDEFINED; + s->current_mapping->info.file.offset =3D 0; + } + s->current_mapping->path=3Dbuffer; + s->current_mapping->read_only =3D + (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) =3D=3D 0; } else { g_free(buffer); } @@ -791,25 +791,25 @@ static int read_directory(BDRVVVFATState* s, int mapp= ing_index) =20 /* fill with zeroes up to the end of the cluster */ while(s->directory.next%(0x10*s->sectors_per_cluster)) { - direntry_t* direntry=3Darray_get_next(&(s->directory)); - memset(direntry,0,sizeof(direntry_t)); + direntry_t* direntry=3Darray_get_next(&(s->directory)); + memset(direntry,0,sizeof(direntry_t)); } =20 /* TODO: if there are more entries, bootsector has to be adjusted! */ #define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster) if (mapping_index =3D=3D 0 && s->directory.next < ROOT_ENTRIES) { - /* root directory */ - int cur =3D s->directory.next; - array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); - s->directory.next =3D ROOT_ENTRIES; - memset(array_get(&(s->directory), cur), 0, - (ROOT_ENTRIES - cur) * sizeof(direntry_t)); + /* root directory */ + int cur =3D s->directory.next; + array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); + s->directory.next =3D ROOT_ENTRIES; + memset(array_get(&(s->directory), cur), 0, + (ROOT_ENTRIES - cur) * sizeof(direntry_t)); } =20 /* reget the mapping, since s->mapping was possibly realloc()ed */ mapping =3D array_get(&(s->mapping), mapping_index); first_cluster +=3D (s->directory.next - mapping->info.dir.first_dir_in= dex) - * 0x20 / s->cluster_size; + * 0x20 / s->cluster_size; mapping->end =3D first_cluster; =20 direntry =3D array_get(&(s->directory), mapping->dir_index); @@ -857,8 +857,8 @@ static int init_directories(BDRVVVFATState* s, =20 /* add volume label */ { - direntry_t* entry=3Darray_get_next(&(s->directory)); - entry->attributes=3D0x28; /* archive | volume label */ + direntry_t* entry=3Darray_get_next(&(s->directory)); + entry->attributes=3D0x28; /* archive | volume label */ memcpy(entry->name, s->volume_label, sizeof(entry->name)); } =20 @@ -876,61 +876,61 @@ static int init_directories(BDRVVVFATState* s, mapping->path =3D g_strdup(dirname); i =3D strlen(mapping->path); if (i > 0 && mapping->path[i - 1] =3D=3D '/') - mapping->path[i - 1] =3D '\0'; + mapping->path[i - 1] =3D '\0'; mapping->mode =3D MODE_DIRECTORY; mapping->read_only =3D 0; s->path =3D mapping->path; =20 for (i =3D 0, cluster =3D 0; i < s->mapping.next; i++) { - /* MS-DOS expects the FAT to be 0 for the root directory - * (except for the media byte). */ - /* LATER TODO: still true for FAT32? */ - int fix_fat =3D (i !=3D 0); - mapping =3D array_get(&(s->mapping), i); + /* MS-DOS expects the FAT to be 0 for the root directory + * (except for the media byte). */ + /* LATER TODO: still true for FAT32? */ + int fix_fat =3D (i !=3D 0); + mapping =3D array_get(&(s->mapping), i); =20 if (mapping->mode & MODE_DIRECTORY) { - mapping->begin =3D cluster; - if(read_directory(s, i)) { + mapping->begin =3D cluster; + if(read_directory(s, i)) { error_setg(errp, "Could not read directory %s", mapping->path); - return -1; - } - mapping =3D array_get(&(s->mapping), i); - } else { - assert(mapping->mode =3D=3D MODE_UNDEFINED); - mapping->mode=3DMODE_NORMAL; - mapping->begin =3D cluster; - if (mapping->end > 0) { - direntry_t* direntry =3D array_get(&(s->directory), - mapping->dir_index); - - mapping->end =3D cluster + 1 + (mapping->end-1)/s->cluster_size; - set_begin_of_direntry(direntry, mapping->begin); - } else { - mapping->end =3D cluster + 1; - fix_fat =3D 0; - } - } - - assert(mapping->begin < mapping->end); - - /* next free cluster */ - cluster =3D mapping->end; - - if(cluster > s->cluster_count) { + return -1; + } + mapping =3D array_get(&(s->mapping), i); + } else { + assert(mapping->mode =3D=3D MODE_UNDEFINED); + mapping->mode=3DMODE_NORMAL; + mapping->begin =3D cluster; + if (mapping->end > 0) { + direntry_t* direntry =3D array_get(&(s->directory), + mapping->dir_index); + + mapping->end =3D cluster + 1 + (mapping->end-1)/s->cluster= _size; + set_begin_of_direntry(direntry, mapping->begin); + } else { + mapping->end =3D cluster + 1; + fix_fat =3D 0; + } + } + + assert(mapping->begin < mapping->end); + + /* next free cluster */ + cluster =3D mapping->end; + + if(cluster > s->cluster_count) { error_setg(errp, "Directory does not fit in FAT%d (capacity %.2f MB)= ", s->fat_type, s->sector_count / 2000.0); return -1; - } + } =20 - /* fix fat for entry */ - if (fix_fat) { - int j; - for(j =3D mapping->begin; j < mapping->end - 1; j++) - fat_set(s, j, j+1); - fat_set(s, mapping->end - 1, s->max_fat_value); - } + /* fix fat for entry */ + if (fix_fat) { + int j; + for(j =3D mapping->begin; j < mapping->end - 1; j++) + fat_set(s, j, j+1); + fat_set(s, mapping->end - 1, s->max_fat_value); + } } =20 mapping =3D array_get(&(s->mapping), 0); @@ -1136,7 +1136,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, =20 switch (s->fat_type) { case 32: - fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. " + fprintf(stderr, "Big fat greek warning: FAT32 has not been tes= ted. " "You are welcome to do so!\n"); break; case 16: @@ -1230,11 +1230,11 @@ static void vvfat_refresh_limits(BlockDriverState *= bs, Error **errp) static inline void vvfat_close_current_file(BDRVVVFATState *s) { if(s->current_mapping) { - s->current_mapping =3D NULL; - if (s->current_fd) { - qemu_close(s->current_fd); - s->current_fd =3D 0; - } + s->current_mapping =3D NULL; + if (s->current_fd) { + qemu_close(s->current_fd); + s->current_fd =3D 0; + } } s->current_cluster =3D -1; } @@ -1246,26 +1246,26 @@ static inline int find_mapping_for_cluster_aux(BDRV= VVFATState* s,int cluster_num { while(1) { int index3; - mapping_t* mapping; - index3=3D(index1+index2)/2; - mapping=3Darray_get(&(s->mapping),index3); - assert(mapping->begin < mapping->end); - if(mapping->begin>=3Dcluster_num) { - assert(index2!=3Dindex3 || index2=3D=3D0); - if(index2=3D=3Dindex3) - return index1; - index2=3Dindex3; - } else { - if(index1=3D=3Dindex3) - return mapping->end<=3Dcluster_num ? index2 : index1; - index1=3Dindex3; - } - assert(index1<=3Dindex2); - DLOG(mapping=3Darray_get(&(s->mapping),index1); - assert(mapping->begin<=3Dcluster_num); - assert(index2 >=3D s->mapping.next || - ((mapping =3D array_get(&(s->mapping),index2)) && - mapping->end>cluster_num))); + mapping_t* mapping; + index3=3D(index1+index2)/2; + mapping=3Darray_get(&(s->mapping),index3); + assert(mapping->begin < mapping->end); + if(mapping->begin>=3Dcluster_num) { + assert(index2!=3Dindex3 || index2=3D=3D0); + if(index2=3D=3Dindex3) + return index1; + index2=3Dindex3; + } else { + if(index1=3D=3Dindex3) + return mapping->end<=3Dcluster_num ? index2 : index1; + index1=3Dindex3; + } + assert(index1<=3Dindex2); + DLOG(mapping=3Darray_get(&(s->mapping),index1); + assert(mapping->begin<=3Dcluster_num); + assert(index2 >=3D s->mapping.next || + ((mapping =3D array_get(&(s->mapping),index2)) && + mapping->end>cluster_num))); } } =20 @@ -1285,16 +1285,16 @@ static inline mapping_t* find_mapping_for_cluster(B= DRVVVFATState* s,int cluster_ static int open_file(BDRVVVFATState* s,mapping_t* mapping) { if(!mapping) - return -1; + return -1; if(!s->current_mapping || - strcmp(s->current_mapping->path,mapping->path)) { - /* open file */ - int fd =3D qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE); - if(fd<0) - return -1; - vvfat_close_current_file(s); - s->current_fd =3D fd; - s->current_mapping =3D mapping; + strcmp(s->current_mapping->path,mapping->path)) { + /* open file */ + int fd =3D qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEF= ILE); + if(fd<0) + return -1; + vvfat_close_current_file(s); + s->current_fd =3D fd; + s->current_mapping =3D mapping; } return 0; } @@ -1302,47 +1302,47 @@ static int open_file(BDRVVVFATState* s,mapping_t* m= apping) static inline int read_cluster(BDRVVVFATState *s,int cluster_num) { if(s->current_cluster !=3D cluster_num) { - int result=3D0; - off_t offset; - assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode = & MODE_DIRECTORY)); - if(!s->current_mapping - || s->current_mapping->begin>cluster_num - || s->current_mapping->end<=3Dcluster_num) { - /* binary search of mappings for file */ - mapping_t* mapping=3Dfind_mapping_for_cluster(s,cluster_num); - - assert(!mapping || (cluster_num>=3Dmapping->begin && cluster_numend)); - - if (mapping && mapping->mode & MODE_DIRECTORY) { - vvfat_close_current_file(s); - s->current_mapping =3D mapping; + int result=3D0; + off_t offset; + assert(!s->current_mapping || s->current_fd || (s->current_mapping= ->mode & MODE_DIRECTORY)); + if(!s->current_mapping + || s->current_mapping->begin>cluster_num + || s->current_mapping->end<=3Dcluster_num) { + /* binary search of mappings for file */ + mapping_t* mapping=3Dfind_mapping_for_cluster(s,cluster_num); + + assert(!mapping || (cluster_num>=3Dmapping->begin && cluster_n= umend)); + + if (mapping && mapping->mode & MODE_DIRECTORY) { + vvfat_close_current_file(s); + s->current_mapping =3D mapping; read_cluster_directory: - offset =3D s->cluster_size*(cluster_num-s->current_mapping->begin); - s->cluster =3D (unsigned char*)s->directory.pointer+offset - + 0x20*s->current_mapping->info.dir.first_dir_index; - assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_siz= e)=3D=3D0); - assert((char*)s->cluster+s->cluster_size <=3D s->directory.pointer+s->di= rectory.next*s->directory.item_size); - s->current_cluster =3D cluster_num; - return 0; - } - - if(open_file(s,mapping)) - return -2; - } else if (s->current_mapping->mode & MODE_DIRECTORY) - goto read_cluster_directory; - - assert(s->current_fd); - - offset=3Ds->cluster_size*(cluster_num-s->current_mapping->begin)+s->curre= nt_mapping->info.file.offset; - if(lseek(s->current_fd, offset, SEEK_SET)!=3Doffset) - return -3; - s->cluster=3Ds->cluster_buffer; - result=3Dread(s->current_fd,s->cluster,s->cluster_size); - if(result<0) { - s->current_cluster =3D -1; - return -1; - } - s->current_cluster =3D cluster_num; + offset =3D s->cluster_size*(cluster_num-s->current_mapping= ->begin); + s->cluster =3D (unsigned char*)s->directory.pointer+offset + + 0x20*s->current_mapping->info.dir.first_dir_inde= x; + assert(((s->cluster-(unsigned char*)s->directory.pointer)%= s->cluster_size)=3D=3D0); + assert((char*)s->cluster+s->cluster_size <=3D s->directory= .pointer+s->directory.next*s->directory.item_size); + s->current_cluster =3D cluster_num; + return 0; + } + + if(open_file(s,mapping)) + return -2; + } else if (s->current_mapping->mode & MODE_DIRECTORY) + goto read_cluster_directory; + + assert(s->current_fd); + + offset=3Ds->cluster_size*(cluster_num-s->current_mapping->begin)+s= ->current_mapping->info.file.offset; + if(lseek(s->current_fd, offset, SEEK_SET)!=3Doffset) + return -3; + s->cluster=3Ds->cluster_buffer; + result=3Dread(s->current_fd,s->cluster,s->cluster_size); + if(result<0) { + s->current_cluster =3D -1; + return -1; + } + s->current_cluster =3D cluster_num; } return 0; } @@ -1355,28 +1355,28 @@ static void print_direntry(const direntry_t* dirent= ry) =20 fprintf(stderr, "direntry %p: ", direntry); if(!direntry) - return; + return; if(is_long_name(direntry)) { - unsigned char* c=3D(unsigned char*)direntry; - int i; - for(i=3D1;i<11 && c[i] && c[i]!=3D0xff;i+=3D2) + unsigned char* c=3D(unsigned char*)direntry; + int i; + for(i=3D1;i<11 && c[i] && c[i]!=3D0xff;i+=3D2) #define ADD_CHAR(c) {buffer[j] =3D (c); if (buffer[j] < ' ') buffer[j] =3D= 0xb0; j++;} - ADD_CHAR(c[i]); - for(i=3D14;i<26 && c[i] && c[i]!=3D0xff;i+=3D2) - ADD_CHAR(c[i]); - for(i=3D28;i<32 && c[i] && c[i]!=3D0xff;i+=3D2) - ADD_CHAR(c[i]); - buffer[j] =3D 0; - fprintf(stderr, "%s\n", buffer); + ADD_CHAR(c[i]); + for(i=3D14;i<26 && c[i] && c[i]!=3D0xff;i+=3D2) + ADD_CHAR(c[i]); + for(i=3D28;i<32 && c[i] && c[i]!=3D0xff;i+=3D2) + ADD_CHAR(c[i]); + buffer[j] =3D 0; + fprintf(stderr, "%s\n", buffer); } else { - int i; - for(i=3D0;i<11;i++) - ADD_CHAR(direntry->name[i]); - buffer[j] =3D 0; - fprintf(stderr,"%s attributes=3D0x%02x begin=3D%d size=3D%d\n", - buffer, - direntry->attributes, - begin_of_direntry(direntry),le32_to_cpu(direntry->size)); + int i; + for(i=3D0;i<11;i++) + ADD_CHAR(direntry->name[i]); + buffer[j] =3D 0; + fprintf(stderr,"%s attributes=3D0x%02x begin=3D%d size=3D%d\n", + buffer, + direntry->attributes, + begin_of_direntry(direntry),le32_to_cpu(direntry->size)); } } =20 @@ -1388,9 +1388,9 @@ static void print_mapping(const mapping_t* mapping) mapping->first_mapping_index, mapping->path, mapping->mode); =20 if (mapping->mode & MODE_DIRECTORY) - fprintf(stderr, "parent_mapping_index =3D %d, first_dir_index =3D %d\n", = mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index); + fprintf(stderr, "parent_mapping_index =3D %d, first_dir_index =3D = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_= index); else - fprintf(stderr, "offset =3D %d\n", mapping->info.file.offset); + fprintf(stderr, "offset =3D %d\n", mapping->info.file.offset); } #endif =20 @@ -1401,10 +1401,10 @@ static int vvfat_read(BlockDriverState *bs, int64_t= sector_num, int i; =20 for(i=3D0;i=3D bs->total_sectors) - return -1; - if (s->qcow) { - int n; + if (sector_num >=3D bs->total_sectors) + return -1; + if (s->qcow) { + int n; int ret; ret =3D bdrv_is_allocated(s->qcow->bs, sector_num, nb_sectors - i, &n); @@ -1422,25 +1422,25 @@ static int vvfat_read(BlockDriverState *bs, int64_t= sector_num, continue; } DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); - } - if(sector_numfaked_sectors) { - if(sector_numfirst_sectors_number) - memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200); - else if(sector_num-s->first_sectors_numbersectors_per_fat) - memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)= *0x200]),0x200); - else if(sector_num-s->first_sectors_number-s->sectors_per_fatsect= ors_per_fat) - memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-= s->sectors_per_fat)*0x200]),0x200); - } else { - uint32_t sector=3Dsector_num-s->faked_sectors, - sector_offset_in_cluster=3D(sector%s->sectors_per_cluster), - cluster_num=3Dsector/s->sectors_per_cluster; - if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != =3D 0) { - /* LATER TODO: strict: return -1; */ - memset(buf+i*0x200,0,0x200); - continue; - } - memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200); - } + } + if(sector_numfaked_sectors) { + if(sector_numfirst_sectors_number) + memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0= x200); + else if(sector_num-s->first_sectors_numbersectors_per_fat) + memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_s= ectors_number)*0x200]),0x200); + else if(sector_num-s->first_sectors_number-s->sectors_per_fat<= s->sectors_per_fat) + memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_s= ectors_number-s->sectors_per_fat)*0x200]),0x200); + } else { + uint32_t sector=3Dsector_num-s->faked_sectors, + sector_offset_in_cluster=3D(sector%s->sectors_per_cluster), + cluster_num=3Dsector/s->sectors_per_cluster; + if(cluster_num > s->cluster_count || read_cluster(s, cluster_n= um) !=3D 0) { + /* LATER TODO: strict: return -1; */ + memset(buf+i*0x200,0,0x200); + continue; + } + memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0= x200); + } } return 0; } @@ -1498,14 +1498,14 @@ vvfat_co_preadv(BlockDriverState *bs, uint64_t offs= et, uint64_t bytes, typedef struct commit_t { char* path; union { - struct { uint32_t cluster; } rename; - struct { int dir_index; uint32_t modified_offset; } writeout; - struct { uint32_t first_cluster; } new_file; - struct { uint32_t cluster; } mkdir; + struct { uint32_t cluster; } rename; + struct { int dir_index; uint32_t modified_offset; } writeout; + struct { uint32_t first_cluster; } new_file; + struct { uint32_t cluster; } mkdir; } param; /* DELETEs and RMDIRs are handled differently: see handle_deletes() */ enum { - ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR + ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR } action; } commit_t; =20 @@ -1514,19 +1514,19 @@ static void clear_commits(BDRVVVFATState* s) int i; DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next)); for (i =3D 0; i < s->commits.next; i++) { - commit_t* commit =3D array_get(&(s->commits), i); - assert(commit->path || commit->action =3D=3D ACTION_WRITEOUT); - if (commit->action !=3D ACTION_WRITEOUT) { - assert(commit->path); + commit_t* commit =3D array_get(&(s->commits), i); + assert(commit->path || commit->action =3D=3D ACTION_WRITEOUT); + if (commit->action !=3D ACTION_WRITEOUT) { + assert(commit->path); g_free(commit->path); - } else - assert(commit->path =3D=3D NULL); + } else + assert(commit->path =3D=3D NULL); } s->commits.next =3D 0; } =20 static void schedule_rename(BDRVVVFATState* s, - uint32_t cluster, char* new_path) + uint32_t cluster, char* new_path) { commit_t* commit =3D array_get_next(&(s->commits)); commit->path =3D new_path; @@ -1535,7 +1535,7 @@ static void schedule_rename(BDRVVVFATState* s, } =20 static void schedule_writeout(BDRVVVFATState* s, - int dir_index, uint32_t modified_offset) + int dir_index, uint32_t modified_offset) { commit_t* commit =3D array_get_next(&(s->commits)); commit->path =3D NULL; @@ -1545,7 +1545,7 @@ static void schedule_writeout(BDRVVVFATState* s, } =20 static void schedule_new_file(BDRVVVFATState* s, - char* path, uint32_t first_cluster) + char* path, uint32_t first_cluster) { commit_t* commit =3D array_get_next(&(s->commits)); commit->path =3D path; @@ -1580,72 +1580,72 @@ static void lfn_init(long_file_name* lfn) =20 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */ static int parse_long_name(long_file_name* lfn, - const direntry_t* direntry) + const direntry_t* direntry) { int i, j, offset; const unsigned char* pointer =3D (const unsigned char*)direntry; =20 if (!is_long_name(direntry)) - return 1; + return 1; =20 if (pointer[0] & 0x40) { - lfn->sequence_number =3D pointer[0] & 0x3f; - lfn->checksum =3D pointer[13]; - lfn->name[0] =3D 0; - lfn->name[lfn->sequence_number * 13] =3D 0; + lfn->sequence_number =3D pointer[0] & 0x3f; + lfn->checksum =3D pointer[13]; + lfn->name[0] =3D 0; + lfn->name[lfn->sequence_number * 13] =3D 0; } else if ((pointer[0] & 0x3f) !=3D --lfn->sequence_number) - return -1; + return -1; else if (pointer[13] !=3D lfn->checksum) - return -2; + return -2; else if (pointer[12] || pointer[26] || pointer[27]) - return -3; + return -3; =20 offset =3D 13 * (lfn->sequence_number - 1); for (i =3D 0, j =3D 1; i < 13; i++, j+=3D2) { - if (j =3D=3D 11) - j =3D 14; - else if (j =3D=3D 26) - j =3D 28; + if (j =3D=3D 11) + j =3D 14; + else if (j =3D=3D 26) + j =3D 28; =20 - if (pointer[j+1] =3D=3D 0) - lfn->name[offset + i] =3D pointer[j]; - else if (pointer[j+1] !=3D 0xff || (pointer[0] & 0x40) =3D=3D 0) - return -4; - else - lfn->name[offset + i] =3D 0; + if (pointer[j+1] =3D=3D 0) + lfn->name[offset + i] =3D pointer[j]; + else if (pointer[j+1] !=3D 0xff || (pointer[0] & 0x40) =3D=3D 0) + return -4; + else + lfn->name[offset + i] =3D 0; } =20 if (pointer[0] & 0x40) - lfn->len =3D offset + strlen((char*)lfn->name + offset); + lfn->len =3D offset + strlen((char*)lfn->name + offset); =20 return 0; } =20 /* returns 0 if successful, >0 if no short_name, and <0 on error */ static int parse_short_name(BDRVVVFATState* s, - long_file_name* lfn, direntry_t* direntry) + long_file_name* lfn, direntry_t* direntry) { int i, j; =20 if (!is_short_name(direntry)) - return 1; + return 1; =20 for (j =3D 7; j >=3D 0 && direntry->name[j] =3D=3D ' '; j--); for (i =3D 0; i <=3D j; i++) { - if (direntry->name[i] <=3D ' ' || direntry->name[i] > 0x7f) - return -1; - else if (s->downcase_short_names) - lfn->name[i] =3D qemu_tolower(direntry->name[i]); - else - lfn->name[i] =3D direntry->name[i]; + if (direntry->name[i] <=3D ' ' || direntry->name[i] > 0x7f) + return -1; + else if (s->downcase_short_names) + lfn->name[i] =3D qemu_tolower(direntry->name[i]); + else + lfn->name[i] =3D direntry->name[i]; } =20 for (j =3D 2; j >=3D 0 && direntry->name[8 + j] =3D=3D ' '; j--) { } if (j >=3D 0) { - lfn->name[i++] =3D '.'; - lfn->name[i + j + 1] =3D '\0'; - for (;j >=3D 0; j--) { + lfn->name[i++] =3D '.'; + lfn->name[i + j + 1] =3D '\0'; + for (;j >=3D 0; j--) { uint8_t c =3D direntry->name[8 + j]; if (c <=3D ' ' || c > 0x7f) { return -2; @@ -1654,9 +1654,9 @@ static int parse_short_name(BDRVVVFATState* s, } else { lfn->name[i + j] =3D c; } - } + } } else - lfn->name[i + j + 1] =3D '\0'; + lfn->name[i + j + 1] =3D '\0'; =20 lfn->len =3D strlen((char*)lfn->name); =20 @@ -1664,13 +1664,13 @@ static int parse_short_name(BDRVVVFATState* s, } =20 static inline uint32_t modified_fat_get(BDRVVVFATState* s, - unsigned int cluster) + unsigned int cluster) { if (cluster < s->last_cluster_of_root_directory) { - if (cluster + 1 =3D=3D s->last_cluster_of_root_directory) - return s->max_fat_value; - else - return cluster + 1; + if (cluster + 1 =3D=3D s->last_cluster_of_root_directory) + return s->max_fat_value; + else + return cluster + 1; } =20 if (s->fat_type=3D=3D32) { @@ -1714,9 +1714,9 @@ static const char* get_basename(const char* path) { char* basename =3D strrchr(path, '/'); if (basename =3D=3D NULL) - return path; + return path; else - return basename + 1; /* strip '/' */ + return basename + 1; /* strip '/' */ } =20 /* @@ -1741,7 +1741,7 @@ typedef enum { * assumed to be *not* deleted (and *only* those). */ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s, - direntry_t* direntry, const char* path) + direntry_t* direntry, const char* path) { /* * This is a little bit tricky: @@ -1774,85 +1774,85 @@ static uint32_t get_cluster_count_for_direntry(BDRV= VVFATState* s, =20 /* the root directory */ if (cluster_num =3D=3D 0) - return 0; + return 0; =20 /* write support */ if (s->qcow) { - basename2 =3D get_basename(path); + basename2 =3D get_basename(path); =20 - mapping =3D find_mapping_for_cluster(s, cluster_num); + mapping =3D find_mapping_for_cluster(s, cluster_num); =20 - if (mapping) { - const char* basename; + if (mapping) { + const char* basename; =20 - assert(mapping->mode & MODE_DELETED); - mapping->mode &=3D ~MODE_DELETED; + assert(mapping->mode & MODE_DELETED); + mapping->mode &=3D ~MODE_DELETED; =20 - basename =3D get_basename(mapping->path); + basename =3D get_basename(mapping->path); =20 - assert(mapping->mode & MODE_NORMAL); + assert(mapping->mode & MODE_NORMAL); =20 - /* rename */ - if (strcmp(basename, basename2)) - schedule_rename(s, cluster_num, g_strdup(path)); - } else if (is_file(direntry)) - /* new file */ - schedule_new_file(s, g_strdup(path), cluster_num); - else { + /* rename */ + if (strcmp(basename, basename2)) + schedule_rename(s, cluster_num, g_strdup(path)); + } else if (is_file(direntry)) + /* new file */ + schedule_new_file(s, g_strdup(path), cluster_num); + else { abort(); - return 0; - } + return 0; + } } =20 while(1) { - if (s->qcow) { - if (!copy_it && cluster_was_modified(s, cluster_num)) { - if (mapping =3D=3D NULL || - mapping->begin > cluster_num || - mapping->end <=3D cluster_num) - mapping =3D find_mapping_for_cluster(s, cluster_num); + if (s->qcow) { + if (!copy_it && cluster_was_modified(s, cluster_num)) { + if (mapping =3D=3D NULL || + mapping->begin > cluster_num || + mapping->end <=3D cluster_num) + mapping =3D find_mapping_for_cluster(s, cluster_num); =20 =20 - if (mapping && - (mapping->mode & MODE_DIRECTORY) =3D=3D 0) { + if (mapping && + (mapping->mode & MODE_DIRECTORY) =3D=3D 0) { =20 - /* was modified in qcow */ - if (offset !=3D mapping->info.file.offset + s->cluster_size - * (cluster_num - mapping->begin)) { - /* offset of this cluster in file chain has changed */ + /* was modified in qcow */ + if (offset !=3D mapping->info.file.offset + s->cluster= _size + * (cluster_num - mapping->begin)) { + /* offset of this cluster in file chain has change= d */ abort(); - copy_it =3D 1; - } else if (offset =3D=3D 0) { - const char* basename =3D get_basename(mapping->path); + copy_it =3D 1; + } else if (offset =3D=3D 0) { + const char* basename =3D get_basename(mapping->pat= h); =20 - if (strcmp(basename, basename2)) - copy_it =3D 1; - first_mapping_index =3D array_index(&(s->mapping), mapping); - } + if (strcmp(basename, basename2)) + copy_it =3D 1; + first_mapping_index =3D array_index(&(s->mapping),= mapping); + } =20 - if (mapping->first_mapping_index !=3D first_mapping_index - && mapping->info.file.offset > 0) { + if (mapping->first_mapping_index !=3D first_mapping_in= dex + && mapping->info.file.offset > 0) { abort(); - copy_it =3D 1; - } - - /* need to write out? */ - if (!was_modified && is_file(direntry)) { - was_modified =3D 1; - schedule_writeout(s, mapping->dir_index, offset); - } - } - } - - if (copy_it) { - int i, dummy; - /* - * This is horribly inefficient, but that is okay, since - * it is rarely executed, if at all. - */ - int64_t offset =3D cluster2sector(s, cluster_num); - - vvfat_close_current_file(s); + copy_it =3D 1; + } + + /* need to write out? */ + if (!was_modified && is_file(direntry)) { + was_modified =3D 1; + schedule_writeout(s, mapping->dir_index, offset); + } + } + } + + if (copy_it) { + int i, dummy; + /* + * This is horribly inefficient, but that is okay, since + * it is rarely executed, if at all. + */ + int64_t offset =3D cluster2sector(s, cluster_num); + + vvfat_close_current_file(s); for (i =3D 0; i < s->sectors_per_cluster; i++) { int res; =20 @@ -1871,22 +1871,22 @@ static uint32_t get_cluster_count_for_direntry(BDRV= VVFATState* s, } } } - } - } + } + } =20 - ret++; - if (s->used_clusters[cluster_num] & USED_ANY) - return 0; - s->used_clusters[cluster_num] =3D USED_FILE; + ret++; + if (s->used_clusters[cluster_num] & USED_ANY) + return 0; + s->used_clusters[cluster_num] =3D USED_FILE; =20 - cluster_num =3D modified_fat_get(s, cluster_num); + cluster_num =3D modified_fat_get(s, cluster_num); =20 - if (fat_eof(s, cluster_num)) - return ret; - else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16) - return -1; + if (fat_eof(s, cluster_num)) + return ret; + else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16) + return -1; =20 - offset +=3D s->cluster_size; + offset +=3D s->cluster_size; } } =20 @@ -1896,7 +1896,7 @@ static uint32_t get_cluster_count_for_direntry(BDRVVV= FATState* s, * used by the directory, its subdirectories and their files. */ static int check_directory_consistency(BDRVVVFATState *s, - int cluster_num, const char* path) + int cluster_num, const char* path) { int ret =3D 0; unsigned char* cluster =3D g_malloc(s->cluster_size); @@ -1913,104 +1913,104 @@ static int check_directory_consistency(BDRVVVFATS= tate *s, path2[path_len + 1] =3D '\0'; =20 if (mapping) { - const char* basename =3D get_basename(mapping->path); - const char* basename2 =3D get_basename(path); + const char* basename =3D get_basename(mapping->path); + const char* basename2 =3D get_basename(path); =20 - assert(mapping->mode & MODE_DIRECTORY); + assert(mapping->mode & MODE_DIRECTORY); =20 - assert(mapping->mode & MODE_DELETED); - mapping->mode &=3D ~MODE_DELETED; + assert(mapping->mode & MODE_DELETED); + mapping->mode &=3D ~MODE_DELETED; =20 - if (strcmp(basename, basename2)) - schedule_rename(s, cluster_num, g_strdup(path)); + if (strcmp(basename, basename2)) + schedule_rename(s, cluster_num, g_strdup(path)); } else - /* new directory */ - schedule_mkdir(s, cluster_num, g_strdup(path)); + /* new directory */ + schedule_mkdir(s, cluster_num, g_strdup(path)); =20 lfn_init(&lfn); do { - int i; - int subret =3D 0; + int i; + int subret =3D 0; =20 - ret++; + ret++; =20 - if (s->used_clusters[cluster_num] & USED_ANY) { - fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num); + if (s->used_clusters[cluster_num] & USED_ANY) { + fprintf(stderr, "cluster %d used more than once\n", (int)clust= er_num); goto fail; - } - s->used_clusters[cluster_num] =3D USED_DIRECTORY; + } + s->used_clusters[cluster_num] =3D USED_DIRECTORY; =20 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (i= nt)cluster2sector(s, cluster_num))); - subret =3D vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster, - s->sectors_per_cluster); - if (subret) { - fprintf(stderr, "Error fetching direntries\n"); - fail: + subret =3D vvfat_read(s->bs, cluster2sector(s, cluster_num), clust= er, + s->sectors_per_cluster); + if (subret) { + fprintf(stderr, "Error fetching direntries\n"); + fail: g_free(cluster); - return 0; - } + return 0; + } =20 - for (i =3D 0; i < 0x10 * s->sectors_per_cluster; i++) { - int cluster_count =3D 0; + for (i =3D 0; i < 0x10 * s->sectors_per_cluster; i++) { + int cluster_count =3D 0; =20 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries= + i)); - if (is_volume_label(direntries + i) || is_dot(direntries + i) || - is_free(direntries + i)) - continue; - - subret =3D parse_long_name(&lfn, direntries + i); - if (subret < 0) { - fprintf(stderr, "Error in long name\n"); - goto fail; - } - if (subret =3D=3D 0 || is_free(direntries + i)) - continue; - - if (fat_chksum(direntries+i) !=3D lfn.checksum) { - subret =3D parse_short_name(s, &lfn, direntries + i); - if (subret < 0) { - fprintf(stderr, "Error in short name (%d)\n", subret); - goto fail; - } - if (subret > 0 || !strcmp((char*)lfn.name, ".") - || !strcmp((char*)lfn.name, "..")) - continue; - } - lfn.checksum =3D 0x100; /* cannot use long name twice */ - - if (path_len + 1 + lfn.len >=3D PATH_MAX) { - fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name); - goto fail; - } + if (is_volume_label(direntries + i) || is_dot(direntries + i) = || + is_free(direntries + i)) + continue; + + subret =3D parse_long_name(&lfn, direntries + i); + if (subret < 0) { + fprintf(stderr, "Error in long name\n"); + goto fail; + } + if (subret =3D=3D 0 || is_free(direntries + i)) + continue; + + if (fat_chksum(direntries+i) !=3D lfn.checksum) { + subret =3D parse_short_name(s, &lfn, direntries + i); + if (subret < 0) { + fprintf(stderr, "Error in short name (%d)\n", subret); + goto fail; + } + if (subret > 0 || !strcmp((char*)lfn.name, ".") + || !strcmp((char*)lfn.name, "..")) + continue; + } + lfn.checksum =3D 0x100; /* cannot use long name twice */ + + if (path_len + 1 + lfn.len >=3D PATH_MAX) { + fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name); + goto fail; + } pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1, (char*)lfn.name); =20 - if (is_directory(direntries + i)) { - if (begin_of_direntry(direntries + i) =3D=3D 0) { - DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); pr= int_direntry(direntries + i)); - goto fail; - } - cluster_count =3D check_directory_consistency(s, - begin_of_direntry(direntries + i), path2); - if (cluster_count =3D=3D 0) { - DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_dir= entry(direntries + i)); - goto fail; - } - } else if (is_file(direntries + i)) { - /* check file size with FAT */ - cluster_count =3D get_cluster_count_for_direntry(s, direntries + i, path= 2); - if (cluster_count !=3D + if (is_directory(direntries + i)) { + if (begin_of_direntry(direntries + i) =3D=3D 0) { + DLOG(fprintf(stderr, "invalid begin for directory: %s\= n", path2); print_direntry(direntries + i)); + goto fail; + } + cluster_count =3D check_directory_consistency(s, + begin_of_direntry(direntries + i), path2); + if (cluster_count =3D=3D 0) { + DLOG(fprintf(stderr, "problem in directory %s:\n", pat= h2); print_direntry(direntries + i)); + goto fail; + } + } else if (is_file(direntries + i)) { + /* check file size with FAT */ + cluster_count =3D get_cluster_count_for_direntry(s, dirent= ries + i, path2); + if (cluster_count !=3D DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)= ) { - DLOG(fprintf(stderr, "Cluster count mismatch\n")); - goto fail; - } - } else + DLOG(fprintf(stderr, "Cluster count mismatch\n")); + goto fail; + } + } else abort(); /* cluster_count =3D 0; */ =20 - ret +=3D cluster_count; - } + ret +=3D cluster_count; + } =20 - cluster_num =3D modified_fat_get(s, cluster_num); + cluster_num =3D modified_fat_get(s, cluster_num); } while(!fat_eof(s, cluster_num)); =20 g_free(cluster); @@ -2038,81 +2038,81 @@ DLOG(checkpoint()); * - if all is fine, return number of used clusters */ if (s->fat2 =3D=3D NULL) { - int size =3D 0x200 * s->sectors_per_fat; - s->fat2 =3D g_malloc(size); - memcpy(s->fat2, s->fat.pointer, size); + int size =3D 0x200 * s->sectors_per_fat; + s->fat2 =3D g_malloc(size); + memcpy(s->fat2, s->fat.pointer, size); } check =3D vvfat_read(s->bs, - s->first_sectors_number, s->fat2, s->sectors_per_fat); + s->first_sectors_number, s->fat2, s->sectors_per_fat); if (check) { - fprintf(stderr, "Could not copy fat\n"); - return 0; + fprintf(stderr, "Could not copy fat\n"); + return 0; } assert (s->used_clusters); for (i =3D 0; i < sector2cluster(s, s->sector_count); i++) - s->used_clusters[i] &=3D ~USED_ANY; + s->used_clusters[i] &=3D ~USED_ANY; =20 clear_commits(s); =20 /* mark every mapped file/directory as deleted. * (check_directory_consistency() will unmark those still present). */ if (s->qcow) - for (i =3D 0; i < s->mapping.next; i++) { - mapping_t* mapping =3D array_get(&(s->mapping), i); - if (mapping->first_mapping_index < 0) - mapping->mode |=3D MODE_DELETED; - } + for (i =3D 0; i < s->mapping.next; i++) { + mapping_t* mapping =3D array_get(&(s->mapping), i); + if (mapping->first_mapping_index < 0) + mapping->mode |=3D MODE_DELETED; + } =20 used_clusters_count =3D check_directory_consistency(s, 0, s->path); if (used_clusters_count <=3D 0) { - DLOG(fprintf(stderr, "problem in directory\n")); - return 0; + DLOG(fprintf(stderr, "problem in directory\n")); + return 0; } =20 check =3D s->last_cluster_of_root_directory; for (i =3D check; i < sector2cluster(s, s->sector_count); i++) { - if (modified_fat_get(s, i)) { - if(!s->used_clusters[i]) { - DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n"= , i)); - return 0; - } - check++; - } + if (modified_fat_get(s, i)) { + if(!s->used_clusters[i]) { + DLOG(fprintf(stderr, "FAT was modified (%d), but cluster i= s not used?\n", i)); + return 0; + } + check++; + } =20 - if (s->used_clusters[i] =3D=3D USED_ALLOCATED) { - /* allocated, but not used... */ - DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i)); - return 0; - } + if (s->used_clusters[i] =3D=3D USED_ALLOCATED) { + /* allocated, but not used... */ + DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i)); + return 0; + } } =20 if (check !=3D used_clusters_count) - return 0; + return 0; =20 return used_clusters_count; } =20 static inline void adjust_mapping_indices(BDRVVVFATState* s, - int offset, int adjust) + int offset, int adjust) { int i; =20 for (i =3D 0; i < s->mapping.next; i++) { - mapping_t* mapping =3D array_get(&(s->mapping), i); + mapping_t* mapping =3D array_get(&(s->mapping), i); =20 #define ADJUST_MAPPING_INDEX(name) \ - if (mapping->name >=3D offset) \ - mapping->name +=3D adjust + if (mapping->name >=3D offset) \ + mapping->name +=3D adjust =20 - ADJUST_MAPPING_INDEX(first_mapping_index); - if (mapping->mode & MODE_DIRECTORY) - ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index); + ADJUST_MAPPING_INDEX(first_mapping_index); + if (mapping->mode & MODE_DIRECTORY) + ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index); } } =20 /* insert or update mapping */ static mapping_t* insert_mapping(BDRVVVFATState* s, - uint32_t begin, uint32_t end) + uint32_t begin, uint32_t end) { /* * - find mapping where mapping->begin >=3D begin, @@ -2126,15 +2126,15 @@ static mapping_t* insert_mapping(BDRVVVFATState* s, mapping_t* first_mapping =3D array_get(&(s->mapping), 0); =20 if (index < s->mapping.next && (mapping =3D array_get(&(s->mapping), i= ndex)) - && mapping->begin < begin) { - mapping->end =3D begin; - index++; - mapping =3D array_get(&(s->mapping), index); + && mapping->begin < begin) { + mapping->end =3D begin; + index++; + mapping =3D array_get(&(s->mapping), index); } if (index >=3D s->mapping.next || mapping->begin > begin) { - mapping =3D array_insert(&(s->mapping), index, 1); - mapping->path =3D NULL; - adjust_mapping_indices(s, index, +1); + mapping =3D array_insert(&(s->mapping), index, 1); + mapping->path =3D NULL; + adjust_mapping_indices(s, index, +1); } =20 mapping->begin =3D begin; @@ -2146,8 +2146,8 @@ assert(index + 1 >=3D s->mapping.next || next_mapping->begin >=3D end))); =20 if (s->current_mapping && first_mapping !=3D (mapping_t*)s->mapping.po= inter) - s->current_mapping =3D array_get(&(s->mapping), - s->current_mapping - first_mapping); + s->current_mapping =3D array_get(&(s->mapping), + s->current_mapping - first_mapping); =20 return mapping; } @@ -2169,8 +2169,8 @@ static int remove_mapping(BDRVVVFATState* s, int mapp= ing_index) adjust_mapping_indices(s, mapping_index, -1); =20 if (s->current_mapping && first_mapping !=3D (mapping_t*)s->mapping.po= inter) - s->current_mapping =3D array_get(&(s->mapping), - s->current_mapping - first_mapping); + s->current_mapping =3D array_get(&(s->mapping), + s->current_mapping - first_mapping); =20 return 0; } @@ -2179,17 +2179,17 @@ static void adjust_dirindices(BDRVVVFATState* s, in= t offset, int adjust) { int i; for (i =3D 0; i < s->mapping.next; i++) { - mapping_t* mapping =3D array_get(&(s->mapping), i); - if (mapping->dir_index >=3D offset) - mapping->dir_index +=3D adjust; - if ((mapping->mode & MODE_DIRECTORY) && - mapping->info.dir.first_dir_index >=3D offset) - mapping->info.dir.first_dir_index +=3D adjust; + mapping_t* mapping =3D array_get(&(s->mapping), i); + if (mapping->dir_index >=3D offset) + mapping->dir_index +=3D adjust; + if ((mapping->mode & MODE_DIRECTORY) && + mapping->info.dir.first_dir_index >=3D offset) + mapping->info.dir.first_dir_index +=3D adjust; } } =20 static direntry_t* insert_direntries(BDRVVVFATState* s, - int dir_index, int count) + int dir_index, int count) { /* * make room in s->directory, @@ -2197,7 +2197,7 @@ static direntry_t* insert_direntries(BDRVVVFATState* = s, */ direntry_t* result =3D array_insert(&(s->directory), dir_index, count); if (result =3D=3D NULL) - return NULL; + return NULL; adjust_dirindices(s, dir_index, count); return result; } @@ -2206,7 +2206,7 @@ static int remove_direntries(BDRVVVFATState* s, int d= ir_index, int count) { int ret =3D array_remove_slice(&(s->directory), dir_index, count); if (ret) - return ret; + return ret; adjust_dirindices(s, dir_index, -count); return 0; } @@ -2218,7 +2218,7 @@ static int remove_direntries(BDRVVVFATState* s, int d= ir_index, int count) * adjusted) */ static int commit_mappings(BDRVVVFATState* s, - uint32_t first_cluster, int dir_index) + uint32_t first_cluster, int dir_index) { mapping_t* mapping =3D find_mapping_for_cluster(s, first_cluster); direntry_t* direntry =3D array_get(&(s->directory), dir_index); @@ -2231,71 +2231,71 @@ static int commit_mappings(BDRVVVFATState* s, mapping->first_mapping_index =3D -1; mapping->dir_index =3D dir_index; mapping->mode =3D (dir_index <=3D 0 || is_directory(direntry)) ? - MODE_DIRECTORY : MODE_NORMAL; + MODE_DIRECTORY : MODE_NORMAL; =20 while (!fat_eof(s, cluster)) { - uint32_t c, c1; - - for (c =3D cluster, c1 =3D modified_fat_get(s, c); c + 1 =3D=3D c1; - c =3D c1, c1 =3D modified_fat_get(s, c1)); - - c++; - if (c > mapping->end) { - int index =3D array_index(&(s->mapping), mapping); - int i, max_i =3D s->mapping.next - index; - for (i =3D 1; i < max_i && mapping[i].begin < c; i++); - while (--i > 0) - remove_mapping(s, index + 1); - } - assert(mapping =3D=3D array_get(&(s->mapping), s->mapping.next - 1) - || mapping[1].begin >=3D c); - mapping->end =3D c; - - if (!fat_eof(s, c1)) { - int i =3D find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next); - mapping_t* next_mapping =3D i >=3D s->mapping.next ? NULL : - array_get(&(s->mapping), i); - - if (next_mapping =3D=3D NULL || next_mapping->begin > c1) { - int i1 =3D array_index(&(s->mapping), mapping); - - next_mapping =3D insert_mapping(s, c1, c1+1); - - if (c1 < c) - i1++; - mapping =3D array_get(&(s->mapping), i1); - } - - next_mapping->dir_index =3D mapping->dir_index; - next_mapping->first_mapping_index =3D - mapping->first_mapping_index < 0 ? - array_index(&(s->mapping), mapping) : - mapping->first_mapping_index; - next_mapping->path =3D mapping->path; - next_mapping->mode =3D mapping->mode; - next_mapping->read_only =3D mapping->read_only; - if (mapping->mode & MODE_DIRECTORY) { - next_mapping->info.dir.parent_mapping_index =3D - mapping->info.dir.parent_mapping_index; - next_mapping->info.dir.first_dir_index =3D - mapping->info.dir.first_dir_index + - 0x10 * s->sectors_per_cluster * - (mapping->end - mapping->begin); - } else - next_mapping->info.file.offset =3D mapping->info.file.offset + - mapping->end - mapping->begin; - - mapping =3D next_mapping; - } - - cluster =3D c1; + uint32_t c, c1; + + for (c =3D cluster, c1 =3D modified_fat_get(s, c); c + 1 =3D=3D c1; + c =3D c1, c1 =3D modified_fat_get(s, c1)); + + c++; + if (c > mapping->end) { + int index =3D array_index(&(s->mapping), mapping); + int i, max_i =3D s->mapping.next - index; + for (i =3D 1; i < max_i && mapping[i].begin < c; i++); + while (--i > 0) + remove_mapping(s, index + 1); + } + assert(mapping =3D=3D array_get(&(s->mapping), s->mapping.next - 1) + || mapping[1].begin >=3D c); + mapping->end =3D c; + + if (!fat_eof(s, c1)) { + int i =3D find_mapping_for_cluster_aux(s, c1, 0, s->mapping.ne= xt); + mapping_t* next_mapping =3D i >=3D s->mapping.next ? NULL : + array_get(&(s->mapping), i); + + if (next_mapping =3D=3D NULL || next_mapping->begin > c1) { + int i1 =3D array_index(&(s->mapping), mapping); + + next_mapping =3D insert_mapping(s, c1, c1+1); + + if (c1 < c) + i1++; + mapping =3D array_get(&(s->mapping), i1); + } + + next_mapping->dir_index =3D mapping->dir_index; + next_mapping->first_mapping_index =3D + mapping->first_mapping_index < 0 ? + array_index(&(s->mapping), mapping) : + mapping->first_mapping_index; + next_mapping->path =3D mapping->path; + next_mapping->mode =3D mapping->mode; + next_mapping->read_only =3D mapping->read_only; + if (mapping->mode & MODE_DIRECTORY) { + next_mapping->info.dir.parent_mapping_index =3D + mapping->info.dir.parent_mapping_index; + next_mapping->info.dir.first_dir_index =3D + mapping->info.dir.first_dir_index + + 0x10 * s->sectors_per_cluster * + (mapping->end - mapping->begin); + } else + next_mapping->info.file.offset =3D mapping->info.file.offs= et + + mapping->end - mapping->begin; + + mapping =3D next_mapping; + } + + cluster =3D c1; } =20 return 0; } =20 static int commit_direntries(BDRVVVFATState* s, - int dir_index, int parent_mapping_index) + int dir_index, int parent_mapping_index) { direntry_t* direntry =3D array_get(&(s->directory), dir_index); uint32_t first_cluster =3D dir_index =3D=3D 0 ? 0 : begin_of_direntry(= direntry); @@ -2320,58 +2320,58 @@ DLOG(fprintf(stderr, "commit_direntries for %s, par= ent_mapping_index %d\n", mapp mapping->info.dir.parent_mapping_index =3D parent_mapping_index; =20 if (first_cluster =3D=3D 0) { - old_cluster_count =3D new_cluster_count =3D - s->last_cluster_of_root_directory; + old_cluster_count =3D new_cluster_count =3D + s->last_cluster_of_root_directory; } else { - for (old_cluster_count =3D 0, c =3D first_cluster; !fat_eof(s, c); - c =3D fat_get(s, c)) - old_cluster_count++; + for (old_cluster_count =3D 0, c =3D first_cluster; !fat_eof(s, c); + c =3D fat_get(s, c)) + old_cluster_count++; =20 - for (new_cluster_count =3D 0, c =3D first_cluster; !fat_eof(s, c); - c =3D modified_fat_get(s, c)) - new_cluster_count++; + for (new_cluster_count =3D 0, c =3D first_cluster; !fat_eof(s, c); + c =3D modified_fat_get(s, c)) + new_cluster_count++; } =20 if (new_cluster_count > old_cluster_count) { - if (insert_direntries(s, - current_dir_index + factor * old_cluster_count, - factor * (new_cluster_count - old_cluster_count)) =3D=3D NULL) - return -1; + if (insert_direntries(s, + current_dir_index + factor * old_cluster_count, + factor * (new_cluster_count - old_cluster_count)) =3D=3D N= ULL) + return -1; } else if (new_cluster_count < old_cluster_count) - remove_direntries(s, - current_dir_index + factor * new_cluster_count, - factor * (old_cluster_count - new_cluster_count)); + remove_direntries(s, + current_dir_index + factor * new_cluster_count, + factor * (old_cluster_count - new_cluster_count)); =20 for (c =3D first_cluster; !fat_eof(s, c); c =3D modified_fat_get(s, c)= ) { direntry_t *first_direntry; - void* direntry =3D array_get(&(s->directory), current_dir_index); - int ret =3D vvfat_read(s->bs, cluster2sector(s, c), direntry, - s->sectors_per_cluster); - if (ret) - return ret; + void* direntry =3D array_get(&(s->directory), current_dir_index); + int ret =3D vvfat_read(s->bs, cluster2sector(s, c), direntry, + s->sectors_per_cluster); + if (ret) + return ret; =20 /* The first directory entry on the filesystem is the volume name = */ first_direntry =3D (direntry_t*) s->directory.pointer; assert(!memcmp(first_direntry->name, s->volume_label, 11)); =20 - current_dir_index +=3D factor; + current_dir_index +=3D factor; } =20 ret =3D commit_mappings(s, first_cluster, dir_index); if (ret) - return ret; + return ret; =20 /* recurse */ for (i =3D 0; i < factor * new_cluster_count; i++) { - direntry =3D array_get(&(s->directory), first_dir_index + i); - if (is_directory(direntry) && !is_dot(direntry)) { - mapping =3D find_mapping_for_cluster(s, first_cluster); - assert(mapping->mode & MODE_DIRECTORY); - ret =3D commit_direntries(s, first_dir_index + i, - array_index(&(s->mapping), mapping)); - if (ret) - return ret; - } + direntry =3D array_get(&(s->directory), first_dir_index + i); + if (is_directory(direntry) && !is_dot(direntry)) { + mapping =3D find_mapping_for_cluster(s, first_cluster); + assert(mapping->mode & MODE_DIRECTORY); + ret =3D commit_direntries(s, first_dir_index + i, + array_index(&(s->mapping), mapping)); + if (ret) + return ret; + } } =20 return 0; @@ -2380,7 +2380,7 @@ DLOG(fprintf(stderr, "commit_direntries for %s, paren= t_mapping_index %d\n", mapp /* commit one file (adjust contents, adjust mapping), return first_mapping_index */ static int commit_one_file(BDRVVVFATState* s, - int dir_index, uint32_t offset) + int dir_index, uint32_t offset) { direntry_t* direntry =3D array_get(&(s->directory), dir_index); uint32_t c =3D begin_of_direntry(direntry); @@ -2395,14 +2395,14 @@ static int commit_one_file(BDRVVVFATState* s, assert((offset % s->cluster_size) =3D=3D 0); =20 for (i =3D s->cluster_size; i < offset; i +=3D s->cluster_size) - c =3D modified_fat_get(s, c); + c =3D modified_fat_get(s, c); =20 fd =3D qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666); if (fd < 0) { - fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path, - strerror(errno), errno); + fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path, + strerror(errno), errno); g_free(cluster); - return fd; + return fd; } if (offset > 0) { if (lseek(fd, offset, SEEK_SET) !=3D offset) { @@ -2413,18 +2413,18 @@ static int commit_one_file(BDRVVVFATState* s, } =20 while (offset < size) { - uint32_t c1; - int rest_size =3D (size - offset > s->cluster_size ? - s->cluster_size : size - offset); - int ret; + uint32_t c1; + int rest_size =3D (size - offset > s->cluster_size ? + s->cluster_size : size - offset); + int ret; =20 - c1 =3D modified_fat_get(s, c); + c1 =3D modified_fat_get(s, c); =20 - assert((size - offset =3D=3D 0 && fat_eof(s, c)) || - (size > offset && c >=3D2 && !fat_eof(s, c))); + assert((size - offset =3D=3D 0 && fat_eof(s, c)) || + (size > offset && c >=3D2 && !fat_eof(s, c))); =20 - ret =3D vvfat_read(s->bs, cluster2sector(s, c), - (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200); + ret =3D vvfat_read(s->bs, cluster2sector(s, c), + (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200); =20 if (ret < 0) { qemu_close(fd); @@ -2438,8 +2438,8 @@ static int commit_one_file(BDRVVVFATState* s, return -2; } =20 - offset +=3D rest_size; - c =3D c1; + offset +=3D rest_size; + c =3D c1; } =20 if (ftruncate(fd, size)) { @@ -2460,18 +2460,18 @@ static void check1(BDRVVVFATState* s) { int i; for (i =3D 0; i < s->mapping.next; i++) { - mapping_t* mapping =3D array_get(&(s->mapping), i); - if (mapping->mode & MODE_DELETED) { - fprintf(stderr, "deleted\n"); - continue; - } - assert(mapping->dir_index < s->directory.next); - direntry_t* direntry =3D array_get(&(s->directory), mapping->dir_index); - assert(mapping->begin =3D=3D begin_of_direntry(direntry) || mapping->firs= t_mapping_index >=3D 0); - if (mapping->mode & MODE_DIRECTORY) { - assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_clus= ter * (mapping->end - mapping->begin) <=3D s->directory.next); - assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cl= uster)) =3D=3D 0); - } + mapping_t* mapping =3D array_get(&(s->mapping), i); + if (mapping->mode & MODE_DELETED) { + fprintf(stderr, "deleted\n"); + continue; + } + assert(mapping->dir_index < s->directory.next); + direntry_t* direntry =3D array_get(&(s->directory), mapping->dir_i= ndex); + assert(mapping->begin =3D=3D begin_of_direntry(direntry) || mappin= g->first_mapping_index >=3D 0); + if (mapping->mode & MODE_DIRECTORY) { + assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_p= er_cluster * (mapping->end - mapping->begin) <=3D s->directory.next); + assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors= _per_cluster)) =3D=3D 0); + } } } =20 @@ -2482,43 +2482,43 @@ static void check2(BDRVVVFATState* s) int first_mapping =3D -1; =20 for (i =3D 0; i < s->directory.next; i++) { - direntry_t* direntry =3D array_get(&(s->directory), i); - - if (is_short_name(direntry) && begin_of_direntry(direntry)) { - mapping_t* mapping =3D find_mapping_for_cluster(s, begin_of_direntry(= direntry)); - assert(mapping); - assert(mapping->dir_index =3D=3D i || is_dot(direntry)); - assert(mapping->begin =3D=3D begin_of_direntry(direntry) || is_dot(di= rentry)); - } - - if ((i % (0x10 * s->sectors_per_cluster)) =3D=3D 0) { - /* cluster start */ - int j, count =3D 0; - - for (j =3D 0; j < s->mapping.next; j++) { - mapping_t* mapping =3D array_get(&(s->mapping), j); - if (mapping->mode & MODE_DELETED) - continue; - if (mapping->mode & MODE_DIRECTORY) { - if (mapping->info.dir.first_dir_index <=3D i && mapping->info.dir.fi= rst_dir_index + 0x10 * s->sectors_per_cluster > i) { - assert(++count =3D=3D 1); - if (mapping->first_mapping_index =3D=3D -1) - first_mapping =3D array_index(&(s->mapping), mapping); - else - assert(first_mapping =3D=3D mapping->first_mapping_index); - if (mapping->info.dir.parent_mapping_index < 0) - assert(j =3D=3D 0); - else { - mapping_t* parent =3D array_get(&(s->mapping), mapping->info.dir.pa= rent_mapping_index); - assert(parent->mode & MODE_DIRECTORY); - assert(parent->info.dir.first_dir_index < mapping->info.dir.first_d= ir_index); - } - } - } - } - if (count =3D=3D 0) - first_mapping =3D -1; - } + direntry_t* direntry =3D array_get(&(s->directory), i); + + if (is_short_name(direntry) && begin_of_direntry(direntry)) { + mapping_t* mapping =3D find_mapping_for_cluster(s, begin_of_di= rentry(direntry)); + assert(mapping); + assert(mapping->dir_index =3D=3D i || is_dot(direntry)); + assert(mapping->begin =3D=3D begin_of_direntry(direntry) || is= _dot(direntry)); + } + + if ((i % (0x10 * s->sectors_per_cluster)) =3D=3D 0) { + /* cluster start */ + int j, count =3D 0; + + for (j =3D 0; j < s->mapping.next; j++) { + mapping_t* mapping =3D array_get(&(s->mapping), j); + if (mapping->mode & MODE_DELETED) + continue; + if (mapping->mode & MODE_DIRECTORY) { + if (mapping->info.dir.first_dir_index <=3D i && mappin= g->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) { + assert(++count =3D=3D 1); + if (mapping->first_mapping_index =3D=3D -1) + first_mapping =3D array_index(&(s->mapping), m= apping); + else + assert(first_mapping =3D=3D mapping->first_map= ping_index); + if (mapping->info.dir.parent_mapping_index < 0) + assert(j =3D=3D 0); + else { + mapping_t* parent =3D array_get(&(s->mapping),= mapping->info.dir.parent_mapping_index); + assert(parent->mode & MODE_DIRECTORY); + assert(parent->info.dir.first_dir_index < mapp= ing->info.dir.first_dir_index); + } + } + } + } + if (count =3D=3D 0) + first_mapping =3D -1; + } } } #endif @@ -2530,63 +2530,63 @@ static int handle_renames_and_mkdirs(BDRVVVFATState= * s) #ifdef DEBUG fprintf(stderr, "handle_renames\n"); for (i =3D 0; i < s->commits.next; i++) { - commit_t* commit =3D array_get(&(s->commits), i); - fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(n= ull)", commit->param.rename.cluster, commit->action); + commit_t* commit =3D array_get(&(s->commits), i); + fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->pat= h : "(null)", commit->param.rename.cluster, commit->action); } #endif =20 for (i =3D 0; i < s->commits.next;) { - commit_t* commit =3D array_get(&(s->commits), i); - if (commit->action =3D=3D ACTION_RENAME) { - mapping_t* mapping =3D find_mapping_for_cluster(s, - commit->param.rename.cluster); - char* old_path =3D mapping->path; - - assert(commit->path); - mapping->path =3D commit->path; - if (rename(old_path, mapping->path)) - return -2; - - if (mapping->mode & MODE_DIRECTORY) { - int l1 =3D strlen(mapping->path); - int l2 =3D strlen(old_path); - int diff =3D l1 - l2; - direntry_t* direntry =3D array_get(&(s->directory), - mapping->info.dir.first_dir_index); - uint32_t c =3D mapping->begin; - int i =3D 0; - - /* recurse */ - while (!fat_eof(s, c)) { - do { - direntry_t* d =3D direntry + i; - - if (is_file(d) || (is_directory(d) && !is_dot(d))) { - mapping_t* m =3D find_mapping_for_cluster(s, - begin_of_direntry(d)); - int l =3D strlen(m->path); - char* new_path =3D g_malloc(l + diff + 1); - - assert(!strncmp(m->path, mapping->path, l2)); + commit_t* commit =3D array_get(&(s->commits), i); + if (commit->action =3D=3D ACTION_RENAME) { + mapping_t* mapping =3D find_mapping_for_cluster(s, + commit->param.rename.cluster); + char* old_path =3D mapping->path; + + assert(commit->path); + mapping->path =3D commit->path; + if (rename(old_path, mapping->path)) + return -2; + + if (mapping->mode & MODE_DIRECTORY) { + int l1 =3D strlen(mapping->path); + int l2 =3D strlen(old_path); + int diff =3D l1 - l2; + direntry_t* direntry =3D array_get(&(s->directory), + mapping->info.dir.first_dir_index); + uint32_t c =3D mapping->begin; + int i =3D 0; + + /* recurse */ + while (!fat_eof(s, c)) { + do { + direntry_t* d =3D direntry + i; + + if (is_file(d) || (is_directory(d) && !is_dot(d)))= { + mapping_t* m =3D find_mapping_for_cluster(s, + begin_of_direntry(d)); + int l =3D strlen(m->path); + char* new_path =3D g_malloc(l + diff + 1); + + assert(!strncmp(m->path, mapping->path, l2)); =20 pstrcpy(new_path, l + diff + 1, mapping->path); pstrcpy(new_path + l1, l + diff + 1 - l1, m->path + l2); =20 - schedule_rename(s, m->begin, new_path); - } - i++; - } while((i % (0x10 * s->sectors_per_cluster)) !=3D 0); - c =3D fat_get(s, c); - } - } + schedule_rename(s, m->begin, new_path); + } + i++; + } while((i % (0x10 * s->sectors_per_cluster)) !=3D 0); + c =3D fat_get(s, c); + } + } =20 g_free(old_path); - array_remove(&(s->commits), i); - continue; - } else if (commit->action =3D=3D ACTION_MKDIR) { - mapping_t* mapping; - int j, parent_path_len; + array_remove(&(s->commits), i); + continue; + } else if (commit->action =3D=3D ACTION_MKDIR) { + mapping_t* mapping; + int j, parent_path_len; =20 #ifdef __MINGW32__ if (mkdir(commit->path)) @@ -2596,37 +2596,37 @@ static int handle_renames_and_mkdirs(BDRVVVFATState= * s) return -5; #endif =20 - mapping =3D insert_mapping(s, commit->param.mkdir.cluster, - commit->param.mkdir.cluster + 1); - if (mapping =3D=3D NULL) - return -6; - - mapping->mode =3D MODE_DIRECTORY; - mapping->read_only =3D 0; - mapping->path =3D commit->path; - j =3D s->directory.next; - assert(j); - insert_direntries(s, s->directory.next, - 0x10 * s->sectors_per_cluster); - mapping->info.dir.first_dir_index =3D j; - - parent_path_len =3D strlen(commit->path) - - strlen(get_basename(commit->path)) - 1; - for (j =3D 0; j < s->mapping.next; j++) { - mapping_t* m =3D array_get(&(s->mapping), j); - if (m->first_mapping_index < 0 && m !=3D mapping && - !strncmp(m->path, mapping->path, parent_path_len) && - strlen(m->path) =3D=3D parent_path_len) - break; - } - assert(j < s->mapping.next); - mapping->info.dir.parent_mapping_index =3D j; - - array_remove(&(s->commits), i); - continue; - } - - i++; + mapping =3D insert_mapping(s, commit->param.mkdir.cluster, + commit->param.mkdir.cluster + 1); + if (mapping =3D=3D NULL) + return -6; + + mapping->mode =3D MODE_DIRECTORY; + mapping->read_only =3D 0; + mapping->path =3D commit->path; + j =3D s->directory.next; + assert(j); + insert_direntries(s, s->directory.next, + 0x10 * s->sectors_per_cluster); + mapping->info.dir.first_dir_index =3D j; + + parent_path_len =3D strlen(commit->path) + - strlen(get_basename(commit->path)) - 1; + for (j =3D 0; j < s->mapping.next; j++) { + mapping_t* m =3D array_get(&(s->mapping), j); + if (m->first_mapping_index < 0 && m !=3D mapping && + !strncmp(m->path, mapping->path, parent_path_len) = && + strlen(m->path) =3D=3D parent_path_len) + break; + } + assert(j < s->mapping.next); + mapping->info.dir.parent_mapping_index =3D j; + + array_remove(&(s->commits), i); + continue; + } + + i++; } return 0; } @@ -2641,75 +2641,75 @@ static int handle_commits(BDRVVVFATState* s) vvfat_close_current_file(s); =20 for (i =3D 0; !fail && i < s->commits.next; i++) { - commit_t* commit =3D array_get(&(s->commits), i); - switch(commit->action) { - case ACTION_RENAME: case ACTION_MKDIR: + commit_t* commit =3D array_get(&(s->commits), i); + switch(commit->action) { + case ACTION_RENAME: case ACTION_MKDIR: abort(); - fail =3D -2; - break; - case ACTION_WRITEOUT: { + fail =3D -2; + break; + case ACTION_WRITEOUT: { #ifndef NDEBUG /* these variables are only used by assert() below */ - direntry_t* entry =3D array_get(&(s->directory), - commit->param.writeout.dir_index); - uint32_t begin =3D begin_of_direntry(entry); - mapping_t* mapping =3D find_mapping_for_cluster(s, begin); + direntry_t* entry =3D array_get(&(s->directory), + commit->param.writeout.dir_index); + uint32_t begin =3D begin_of_direntry(entry); + mapping_t* mapping =3D find_mapping_for_cluster(s, begin); #endif =20 - assert(mapping); - assert(mapping->begin =3D=3D begin); - assert(commit->path =3D=3D NULL); - - if (commit_one_file(s, commit->param.writeout.dir_index, - commit->param.writeout.modified_offset)) - fail =3D -3; - - break; - } - case ACTION_NEW_FILE: { - int begin =3D commit->param.new_file.first_cluster; - mapping_t* mapping =3D find_mapping_for_cluster(s, begin); - direntry_t* entry; - int i; - - /* find direntry */ - for (i =3D 0; i < s->directory.next; i++) { - entry =3D array_get(&(s->directory), i); - if (is_file(entry) && begin_of_direntry(entry) =3D=3D begin) - break; - } - - if (i >=3D s->directory.next) { - fail =3D -6; - continue; - } - - /* make sure there exists an initial mapping */ - if (mapping && mapping->begin !=3D begin) { - mapping->end =3D begin; - mapping =3D NULL; - } - if (mapping =3D=3D NULL) { - mapping =3D insert_mapping(s, begin, begin+1); - } - /* most members will be fixed in commit_mappings() */ - assert(commit->path); - mapping->path =3D commit->path; - mapping->read_only =3D 0; - mapping->mode =3D MODE_NORMAL; - mapping->info.file.offset =3D 0; - - if (commit_one_file(s, i, 0)) - fail =3D -7; - - break; - } - default: + assert(mapping); + assert(mapping->begin =3D=3D begin); + assert(commit->path =3D=3D NULL); + + if (commit_one_file(s, commit->param.writeout.dir_index, + commit->param.writeout.modified_offset)) + fail =3D -3; + + break; + } + case ACTION_NEW_FILE: { + int begin =3D commit->param.new_file.first_cluster; + mapping_t* mapping =3D find_mapping_for_cluster(s, begin); + direntry_t* entry; + int i; + + /* find direntry */ + for (i =3D 0; i < s->directory.next; i++) { + entry =3D array_get(&(s->directory), i); + if (is_file(entry) && begin_of_direntry(entry) =3D=3D begi= n) + break; + } + + if (i >=3D s->directory.next) { + fail =3D -6; + continue; + } + + /* make sure there exists an initial mapping */ + if (mapping && mapping->begin !=3D begin) { + mapping->end =3D begin; + mapping =3D NULL; + } + if (mapping =3D=3D NULL) { + mapping =3D insert_mapping(s, begin, begin+1); + } + /* most members will be fixed in commit_mappings() */ + assert(commit->path); + mapping->path =3D commit->path; + mapping->read_only =3D 0; + mapping->mode =3D MODE_NORMAL; + mapping->info.file.offset =3D 0; + + if (commit_one_file(s, i, 0)) + fail =3D -7; + + break; + } + default: abort(); - } + } } if (i > 0 && array_remove_slice(&(s->commits), 0, i)) - return -1; + return -1; return fail; } =20 @@ -2720,53 +2720,53 @@ static int handle_deletes(BDRVVVFATState* s) /* delete files corresponding to mappings marked as deleted */ /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->be= gin) =3D=3D 0) */ while (deferred && deleted) { - deferred =3D 0; - deleted =3D 0; - - for (i =3D 1; i < s->mapping.next; i++) { - mapping_t* mapping =3D array_get(&(s->mapping), i); - if (mapping->mode & MODE_DELETED) { - direntry_t* entry =3D array_get(&(s->directory), - mapping->dir_index); - - if (is_free(entry)) { - /* remove file/directory */ - if (mapping->mode & MODE_DIRECTORY) { - int j, next_dir_index =3D s->directory.next, - first_dir_index =3D mapping->info.dir.first_dir_index; - - if (rmdir(mapping->path) < 0) { - if (errno =3D=3D ENOTEMPTY) { - deferred++; - continue; - } else - return -5; - } - - for (j =3D 1; j < s->mapping.next; j++) { - mapping_t* m =3D array_get(&(s->mapping), j); - if (m->mode & MODE_DIRECTORY && - m->info.dir.first_dir_index > - first_dir_index && - m->info.dir.first_dir_index < - next_dir_index) - next_dir_index =3D - m->info.dir.first_dir_index; - } - remove_direntries(s, first_dir_index, - next_dir_index - first_dir_index); - - deleted++; - } - } else { - if (unlink(mapping->path)) - return -4; - deleted++; - } - DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_= direntry(entry)); - remove_mapping(s, i); - } - } + deferred =3D 0; + deleted =3D 0; + + for (i =3D 1; i < s->mapping.next; i++) { + mapping_t* mapping =3D array_get(&(s->mapping), i); + if (mapping->mode & MODE_DELETED) { + direntry_t* entry =3D array_get(&(s->directory), + mapping->dir_index); + + if (is_free(entry)) { + /* remove file/directory */ + if (mapping->mode & MODE_DIRECTORY) { + int j, next_dir_index =3D s->directory.next, + first_dir_index =3D mapping->info.dir.first_dir_in= dex; + + if (rmdir(mapping->path) < 0) { + if (errno =3D=3D ENOTEMPTY) { + deferred++; + continue; + } else + return -5; + } + + for (j =3D 1; j < s->mapping.next; j++) { + mapping_t* m =3D array_get(&(s->mapping), j); + if (m->mode & MODE_DIRECTORY && + m->info.dir.first_dir_index > + first_dir_index && + m->info.dir.first_dir_index < + next_dir_index) + next_dir_index =3D + m->info.dir.first_dir_index; + } + remove_direntries(s, first_dir_index, + next_dir_index - first_dir_index); + + deleted++; + } + } else { + if (unlink(mapping->path)) + return -4; + deleted++; + } + DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(ma= pping); print_direntry(entry)); + remove_mapping(s, i); + } + } } =20 return 0; @@ -2786,15 +2786,15 @@ static int do_commit(BDRVVVFATState* s) =20 /* the real meat are the commits. Nothing to do? Move along! */ if (s->commits.next =3D=3D 0) - return 0; + return 0; =20 vvfat_close_current_file(s); =20 ret =3D handle_renames_and_mkdirs(s); if (ret) { - fprintf(stderr, "Error handling renames (%d)\n", ret); + fprintf(stderr, "Error handling renames (%d)\n", ret); abort(); - return ret; + return ret; } =20 /* copy FAT (with bdrv_read) */ @@ -2803,23 +2803,23 @@ static int do_commit(BDRVVVFATState* s) /* recurse direntries from root (using bs->bdrv_read) */ ret =3D commit_direntries(s, 0, -1); if (ret) { - fprintf(stderr, "Fatal: error while committing (%d)\n", ret); + fprintf(stderr, "Fatal: error while committing (%d)\n", ret); abort(); - return ret; + return ret; } =20 ret =3D handle_commits(s); if (ret) { - fprintf(stderr, "Error handling commits (%d)\n", ret); + fprintf(stderr, "Error handling commits (%d)\n", ret); abort(); - return ret; + return ret; } =20 ret =3D handle_deletes(s); if (ret) { - fprintf(stderr, "Error deleting\n"); + fprintf(stderr, "Error deleting\n"); abort(); - return ret; + return ret; } =20 if (s->qcow->bs->drv->bdrv_make_empty) { @@ -2837,7 +2837,7 @@ static int try_commit(BDRVVVFATState* s) vvfat_close_current_file(s); DLOG(checkpoint()); if(!is_consistent(s)) - return -1; + return -1; return do_commit(s); } =20 @@ -2863,56 +2863,56 @@ DLOG(checkpoint()); */ =20 if (sector_num < s->first_sectors_number) - return -1; + return -1; =20 for (i =3D sector2cluster(s, sector_num); - i <=3D sector2cluster(s, sector_num + nb_sectors - 1);) { - mapping_t* mapping =3D find_mapping_for_cluster(s, i); - if (mapping) { - if (mapping->read_only) { - fprintf(stderr, "Tried to write to write-protected file %s\n", - mapping->path); - return -1; - } - - if (mapping->mode & MODE_DIRECTORY) { - int begin =3D cluster2sector(s, i); - int end =3D begin + s->sectors_per_cluster, k; - int dir_index; - const direntry_t* direntries; - long_file_name lfn; - - lfn_init(&lfn); - - if (begin < sector_num) - begin =3D sector_num; - if (end > sector_num + nb_sectors) - end =3D sector_num + nb_sectors; - dir_index =3D mapping->dir_index + - 0x10 * (begin - mapping->begin * s->sectors_per_cluster); - direntries =3D (direntry_t*)(buf + 0x200 * (begin - sector_num)); - - for (k =3D 0; k < (end - begin) * 0x10; k++) { - /* do not allow non-ASCII filenames */ - if (parse_long_name(&lfn, direntries + k) < 0) { - fprintf(stderr, "Warning: non-ASCII filename\n"); - return -1; - } - /* no access to the direntry of a read-only file */ - else if (is_short_name(direntries+k) && - (direntries[k].attributes & 1)) { - if (memcmp(direntries + k, - array_get(&(s->directory), dir_index + k), - sizeof(direntry_t))) { - fprintf(stderr, "Warning: tried to write to write-protected file\n"= ); - return -1; - } - } - } - } - i =3D mapping->end; - } else - i++; + i <=3D sector2cluster(s, sector_num + nb_sectors - 1);) { + mapping_t* mapping =3D find_mapping_for_cluster(s, i); + if (mapping) { + if (mapping->read_only) { + fprintf(stderr, "Tried to write to write-protected file %s= \n", + mapping->path); + return -1; + } + + if (mapping->mode & MODE_DIRECTORY) { + int begin =3D cluster2sector(s, i); + int end =3D begin + s->sectors_per_cluster, k; + int dir_index; + const direntry_t* direntries; + long_file_name lfn; + + lfn_init(&lfn); + + if (begin < sector_num) + begin =3D sector_num; + if (end > sector_num + nb_sectors) + end =3D sector_num + nb_sectors; + dir_index =3D mapping->dir_index + + 0x10 * (begin - mapping->begin * s->sectors_per_cluste= r); + direntries =3D (direntry_t*)(buf + 0x200 * (begin - sector= _num)); + + for (k =3D 0; k < (end - begin) * 0x10; k++) { + /* do not allow non-ASCII filenames */ + if (parse_long_name(&lfn, direntries + k) < 0) { + fprintf(stderr, "Warning: non-ASCII filename\n"); + return -1; + } + /* no access to the direntry of a read-only file */ + else if (is_short_name(direntries+k) && + (direntries[k].attributes & 1)) { + if (memcmp(direntries + k, + array_get(&(s->directory), dir_index += k), + sizeof(direntry_t))) { + fprintf(stderr, "Warning: tried to write to wr= ite-protected file\n"); + return -1; + } + } + } + } + i =3D mapping->end; + } else + i++; } =20 /* @@ -2921,14 +2921,14 @@ DLOG(checkpoint()); DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, = nb_sectors)); ret =3D bdrv_write(s->qcow, sector_num, buf, nb_sectors); if (ret < 0) { - fprintf(stderr, "Error writing to qcow backend\n"); - return ret; + fprintf(stderr, "Error writing to qcow backend\n"); + return ret; } =20 for (i =3D sector2cluster(s, sector_num); - i <=3D sector2cluster(s, sector_num + nb_sectors - 1); i++) - if (i >=3D 0) - s->used_clusters[i] |=3D USED_ALLOCATED; + i <=3D sector2cluster(s, sector_num + nb_sectors - 1); i++) + if (i >=3D 0) + s->used_clusters[i] |=3D USED_ALLOCATED; =20 DLOG(checkpoint()); /* TODO: add timeout */ @@ -2967,7 +2967,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offse= t, uint64_t bytes, } =20 static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file) + int64_t sector_num, int nb_sectors, int *n, BlockDriverState **fil= e) { *n =3D bs->total_sectors - sector_num; if (*n > nb_sectors) { @@ -3146,13 +3146,13 @@ static void checkpoint(void) { assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mappi= ng->mode & MODE_DIRECTORY)); #if 0 if (((direntry_t*)vvv->directory.pointer)[1].attributes !=3D 0xf) - fprintf(stderr, "Nonono!\n"); + fprintf(stderr, "Nonono!\n"); mapping_t* mapping; direntry_t* direntry; assert(vvv->mapping.size >=3D vvv->mapping.item_size * vvv->mapping.ne= xt); assert(vvv->directory.size >=3D vvv->directory.item_size * vvv->direct= ory.next); if (vvv->mapping.next<47) - return; + return; assert((mapping =3D array_get(&(vvv->mapping), 47))); assert(mapping->dir_index < vvv->directory.next); direntry =3D array_get(&(vvv->directory), mapping->dir_index); --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487678200283.4528720036959; Mon, 22 May 2017 14:14:38 -0700 (PDT) Received: from localhost ([::1]:44926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuey-0000wW-G1 for importer@patchew.org; Mon, 22 May 2017 17:14:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37311) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuco-0007dY-V3 for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCucn-00007y-SP for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:22 -0400 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:2063) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuci-0008Vl-U0; Mon, 22 May 2017 17:12:17 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id C50EB2003DB; Mon, 22 May 2017 23:12:14 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:55 +0200 Message-Id: <20170522211205.14265-4-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH v2 03/13] vvfat: fix typos X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d3afb731b6..8b5f53ad26 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -404,9 +404,9 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int h= eads, int secs) /* FAT12/FAT16/FAT32 */ /* DOS uses different types when partition is LBA, probably to prevent older versions from using CHS on them */ - partition->fs_type=3D s->fat_type=3D=3D12 ? 0x1: - s->fat_type=3D=3D16 ? (lba?0xe:0x06): - /*fat_tyoe=3D=3D32*/ (lba?0xc:0x0b); + partition->fs_type =3D s->fat_type =3D=3D 12 ? 0x1 : + s->fat_type =3D=3D 16 ? (lba ? 0xe : 0x06) : + /*s->fat_type =3D=3D 32*/ (lba ? 0xc : 0x0b); =20 real_mbr->magic[0]=3D0x55; real_mbr->magic[1]=3D0xaa; } @@ -806,7 +806,7 @@ static int read_directory(BDRVVVFATState* s, int mappin= g_index) (ROOT_ENTRIES - cur) * sizeof(direntry_t)); } =20 - /* reget the mapping, since s->mapping was possibly realloc()ed */ + /* re-get the mapping, since s->mapping was possibly realloc()ed */ mapping =3D array_get(&(s->mapping), mapping_index); first_cluster +=3D (s->directory.next - mapping->info.dir.first_dir_in= dex) * 0x20 / s->cluster_size; --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495488136390851.8151294940039; Mon, 22 May 2017 14:22:16 -0700 (PDT) Received: from localhost ([::1]:44978 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCumM-0007BC-Vl for importer@patchew.org; Mon, 22 May 2017 17:22:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37352) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007eD-Lo for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008v-KB for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36818) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuci-0008Vo-To; Mon, 22 May 2017 17:12:17 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 38D2F2003D5; Mon, 22 May 2017 23:12:15 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:56 +0200 Message-Id: <20170522211205.14265-5-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" MODE_FAKED and MODE_RENAMED are not and were never used. Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 8b5f53ad26..6a36d4f7fa 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -287,8 +287,7 @@ typedef struct mapping_t { union { /* offset is * - the offset in the file (in clusters) for a file, or - * - the next cluster of the directory for a directory, and - * - the address of the buffer for a faked entry + * - the next cluster of the directory for a directory */ struct { uint32_t offset; @@ -301,9 +300,13 @@ typedef struct mapping_t { /* path contains the full path, i.e. it always starts with s->path */ char* path; =20 - enum { MODE_UNDEFINED =3D 0, MODE_NORMAL =3D 1, MODE_MODIFIED =3D 2, - MODE_DIRECTORY =3D 4, MODE_FAKED =3D 8, - MODE_DELETED =3D 16, MODE_RENAMED =3D 32 } mode; + enum { + MODE_UNDEFINED =3D 0, + MODE_NORMAL =3D 1, + MODE_MODIFIED =3D 2, + MODE_DIRECTORY =3D 4, + MODE_DELETED =3D 8, + } mode; int read_only; } mapping_t; =20 --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495488037045216.38909466711948; Mon, 22 May 2017 14:20:37 -0700 (PDT) Received: from localhost ([::1]:44961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCukl-0005sU-BZ for importer@patchew.org; Mon, 22 May 2017 17:20:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37393) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucq-0007f9-As for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008V-BJ for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36935) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCucj-0008WG-Tj; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id A3A162003AC; Mon, 22 May 2017 23:12:15 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:57 +0200 Message-Id: <20170522211205.14265-6-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" - offset_to_bootsector is the number of sectors up to FAT bootsector - offset_to_fat is the number of sectors up to first File Allocation Table - offset_to_root_dir is the number of sectors up to root directory sector Replace first_sectors_number - 1 by offset_to_bootsector. Replace first_sectors_number by offset_to_fat. Replace faked_sectors by offset_to_rootdir. Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 70 ++++++++++++++++++++++++++++++++++++-------------------= ---- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 6a36d4f7fa..e694d82df4 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -320,22 +320,24 @@ static void print_mapping(const struct mapping_t* map= ping); typedef struct BDRVVVFATState { CoMutex lock; BlockDriverState* bs; /* pointer to parent */ - unsigned int first_sectors_number; /* 1 for a single partition, 0x40 f= or a disk with partition table */ unsigned char first_sectors[0x40*0x200]; =20 int fat_type; /* 16 or 32 */ array_t fat,directory,mapping; char volume_label[11]; =20 + uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */ + unsigned int cluster_size; unsigned int sectors_per_cluster; unsigned int sectors_per_fat; unsigned int sectors_of_root_directory; uint32_t last_cluster_of_root_directory; - unsigned int faked_sectors; /* how many sectors are faked before file = data */ uint32_t sector_count; /* total number of sectors of the partition */ uint32_t cluster_count; /* total number of clusters of this partition = */ uint32_t max_fat_value; + uint32_t offset_to_fat; + uint32_t offset_to_root_dir; =20 int current_fd; mapping_t* current_mapping; @@ -394,15 +396,15 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int= heads, int secs) partition->attributes=3D0x80; /* bootable */ =20 /* LBA is used when partition is outside the CHS geometry */ - lba =3D sector2CHS(&partition->start_CHS, s->first_sectors_number - 1, + lba =3D sector2CHS(&partition->start_CHS, s->offset_to_bootsector, cyls, heads, secs); lba |=3D sector2CHS(&partition->end_CHS, s->bs->total_sectors - 1, cyls, heads, secs); =20 /*LBA partitions are identified only by start/length_sector_long not b= y CHS*/ - partition->start_sector_long =3D cpu_to_le32(s->first_sectors_number = - 1); + partition->start_sector_long =3D cpu_to_le32(s->offset_to_bootsector); partition->length_sector_long =3D cpu_to_le32(s->bs->total_sectors - - s->first_sectors_number = + 1); + - s->offset_to_bootsector); =20 /* FAT12/FAT16/FAT32 */ /* DOS uses different types when partition is LBA, @@ -823,12 +825,12 @@ static int read_directory(BDRVVVFATState* s, int mapp= ing_index) =20 static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) { - return (sector_num-s->faked_sectors)/s->sectors_per_cluster; + return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster; } =20 static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num) { - return s->faked_sectors + s->sectors_per_cluster * cluster_num; + return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num; } =20 static int init_directories(BDRVVVFATState* s, @@ -855,6 +857,9 @@ static int init_directories(BDRVVVFATState* s, i =3D 1+s->sectors_per_cluster*0x200*8/s->fat_type; s->sectors_per_fat=3D(s->sector_count+i)/i; /* round up */ =20 + s->offset_to_fat =3D s->offset_to_bootsector + 1; + s->offset_to_root_dir =3D s->offset_to_fat + s->sectors_per_fat * 2; + array_init(&(s->mapping),sizeof(mapping_t)); array_init(&(s->directory),sizeof(direntry_t)); =20 @@ -868,7 +873,6 @@ static int init_directories(BDRVVVFATState* s, /* Now build FAT, and write back information into directory */ init_fat(s); =20 - s->faked_sectors=3Ds->first_sectors_number+s->sectors_per_fat*2; s->cluster_count=3Dsector2cluster(s, s->sector_count); =20 mapping =3D array_get_next(&(s->mapping)); @@ -946,7 +950,8 @@ static int init_directories(BDRVVVFATState* s, =20 s->current_mapping =3D NULL; =20 - bootsector=3D(bootsector_t*)(s->first_sectors+(s->first_sectors_number= -1)*0x200); + bootsector =3D (bootsector_t *)(s->first_sectors + + s->offset_to_bootsector * 0x200); bootsector->jump[0]=3D0xeb; bootsector->jump[1]=3D0x3e; bootsector->jump[2]=3D0x90; @@ -957,16 +962,18 @@ static int init_directories(BDRVVVFATState* s, bootsector->number_of_fats=3D0x2; /* number of FATs */ bootsector->root_entries=3Dcpu_to_le16(s->sectors_of_root_directory*0x= 10); bootsector->total_sectors16=3Ds->sector_count>0xffff?0:cpu_to_le16(s->= sector_count); - bootsector->media_type=3D(s->first_sectors_number>1?0xf8:0xf0); /* med= ia descriptor (f8=3Dhd, f0=3D3.5 fd)*/ + /* media descriptor: hard disk=3D0xf8, floppy=3D0xf0 */ + bootsector->media_type =3D (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0); s->fat.pointer[0] =3D bootsector->media_type; bootsector->sectors_per_fat=3Dcpu_to_le16(s->sectors_per_fat); bootsector->sectors_per_track =3D cpu_to_le16(secs); bootsector->number_of_heads =3D cpu_to_le16(heads); - bootsector->hidden_sectors=3Dcpu_to_le32(s->first_sectors_number=3D=3D= 1?0:0x3f); + bootsector->hidden_sectors =3D cpu_to_le32(s->offset_to_bootsector); bootsector->total_sectors=3Dcpu_to_le32(s->sector_count>0xffff?s->sect= or_count:0); =20 /* LATER TODO: if FAT32, this is wrong */ - bootsector->u.fat16.drive_number=3Ds->first_sectors_number=3D=3D1?0:0x= 80; /* fda=3D0, hda=3D0x80 */ + /* drive_number: fda=3D0, hda=3D0x80 */ + bootsector->u.fat16.drive_number =3D s->offset_to_bootsector =3D=3D 0 = ? 0 : 0x80; bootsector->u.fat16.current_head=3D0; bootsector->u.fat16.signature=3D0x29; bootsector->u.fat16.id=3Dcpu_to_le32(0xfabe1afd); @@ -1123,7 +1130,6 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, secs =3D s->fat_type =3D=3D 12 ? 18 : 36; s->sectors_per_cluster =3D 1; } - s->first_sectors_number =3D 1; cyls =3D 80; heads =3D 2; } else { @@ -1131,7 +1137,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, if (!s->fat_type) { s->fat_type =3D 16; } - s->first_sectors_number =3D 0x40; + s->offset_to_bootsector =3D 0x3f; cyls =3D s->fat_type =3D=3D 12 ? 64 : 1024; heads =3D 16; secs =3D 63; @@ -1167,7 +1173,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, fprintf(stderr, "vvfat %s chs %d,%d,%d\n", dirname, cyls, heads, secs); =20 - s->sector_count =3D cyls * heads * secs - (s->first_sectors_number - 1= ); + s->sector_count =3D cyls * heads * secs - s->offset_to_bootsector; =20 if (qemu_opt_get_bool(opts, "rw", false)) { if (!bdrv_is_read_only(bs)) { @@ -1197,7 +1203,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, goto fail; } =20 - s->sector_count =3D s->faked_sectors + s->sectors_per_cluster*s->clust= er_count; + s->sector_count =3D s->offset_to_root_dir + + s->sectors_per_cluster * s->cluster_count; =20 /* Disable migration when vvfat is used rw */ if (s->qcow) { @@ -1213,7 +1220,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *op= tions, int flags, } } =20 - if (s->first_sectors_number =3D=3D 0x40) { + if (s->offset_to_bootsector > 0) { init_mbr(s, cyls, heads, secs); } =20 @@ -1426,15 +1433,24 @@ static int vvfat_read(BlockDriverState *bs, int64_t= sector_num, } DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); } - if(sector_numfaked_sectors) { - if(sector_numfirst_sectors_number) - memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0= x200); - else if(sector_num-s->first_sectors_numbersectors_per_fat) - memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_s= ectors_number)*0x200]),0x200); - else if(sector_num-s->first_sectors_number-s->sectors_per_fat<= s->sectors_per_fat) - memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_s= ectors_number-s->sectors_per_fat)*0x200]),0x200); + if (sector_num < s->offset_to_root_dir) { + if (sector_num < s->offset_to_fat) { + memcpy(buf + i * 0x200, + &(s->first_sectors[sector_num * 0x200]), + 0x200); + } else if (sector_num < s->offset_to_fat + s->sectors_per_fat)= { + memcpy(buf + i * 0x200, + &(s->fat.pointer[(sector_num + - s->offset_to_fat) * 0x200]), + 0x200); + } else if (sector_num < s->offset_to_root_dir) { + memcpy(buf + i * 0x200, + &(s->fat.pointer[(sector_num - s->offset_to_fat + - s->sectors_per_fat) * 0x200]), + 0x200); + } } else { - uint32_t sector=3Dsector_num-s->faked_sectors, + uint32_t sector =3D sector_num - s->offset_to_root_dir, sector_offset_in_cluster=3D(sector%s->sectors_per_cluster), cluster_num=3Dsector/s->sectors_per_cluster; if(cluster_num > s->cluster_count || read_cluster(s, cluster_n= um) !=3D 0) { @@ -2046,7 +2062,7 @@ DLOG(checkpoint()); memcpy(s->fat2, s->fat.pointer, size); } check =3D vvfat_read(s->bs, - s->first_sectors_number, s->fat2, s->sectors_per_fat); + s->offset_to_fat, s->fat2, s->sectors_per_fat); if (check) { fprintf(stderr, "Could not copy fat\n"); return 0; @@ -2865,7 +2881,7 @@ DLOG(checkpoint()); * - do not allow to write non-ASCII filenames */ =20 - if (sector_num < s->first_sectors_number) + if (sector_num < s->offset_to_fat) return -1; =20 for (i =3D sector2cluster(s, sector_num); --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495488003281931.2086421405475; Mon, 22 May 2017 14:20:03 -0700 (PDT) Received: from localhost ([::1]:44953 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCukD-0005Nv-84 for importer@patchew.org; Mon, 22 May 2017 17:20:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37331) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007dp-9A for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-000084-0c for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:2208) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuck-0008WI-7b; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 144FA2003E8; Mon, 22 May 2017 23:12:16 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:58 +0200 Message-Id: <20170522211205.14265-7-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Specification: "FAT: General overview of on-disk format" v1.03, pages 11-13 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index e694d82df4..c1034cdd1f 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -218,23 +218,30 @@ typedef struct bootsector_t { union { struct { uint8_t drive_number; - uint8_t current_head; + uint8_t reserved1; uint8_t signature; uint32_t id; uint8_t volume_label[11]; + uint8_t fat_type[8]; + uint8_t ignored[0x1c0]; } QEMU_PACKED fat16; struct { uint32_t sectors_per_fat; uint16_t flags; uint8_t major,minor; - uint32_t first_cluster_of_root_directory; + uint32_t first_cluster_of_root_dir; uint16_t info_sector; uint16_t backup_boot_sector; - uint16_t ignored; + uint8_t reserved[12]; + uint8_t drive_number; + uint8_t reserved1; + uint8_t signature; + uint32_t id; + uint8_t volume_label[11]; + uint8_t fat_type[8]; + uint8_t ignored[0x1a4]; } QEMU_PACKED fat32; } u; - uint8_t fat_type[8]; - uint8_t ignored[0x1c0]; uint8_t magic[2]; } QEMU_PACKED bootsector_t; =20 @@ -974,13 +981,13 @@ static int init_directories(BDRVVVFATState* s, /* LATER TODO: if FAT32, this is wrong */ /* drive_number: fda=3D0, hda=3D0x80 */ bootsector->u.fat16.drive_number =3D s->offset_to_bootsector =3D=3D 0 = ? 0 : 0x80; - bootsector->u.fat16.current_head=3D0; bootsector->u.fat16.signature=3D0x29; bootsector->u.fat16.id=3Dcpu_to_le32(0xfabe1afd); =20 memcpy(bootsector->u.fat16.volume_label, s->volume_label, sizeof(bootsector->u.fat16.volume_label)); - memcpy(bootsector->fat_type,(s->fat_type=3D=3D12?"FAT12 ":s->fat_typ= e=3D=3D16?"FAT16 ":"FAT32 "),8); + memcpy(bootsector->u.fat16.fat_type, + s->fat_type =3D=3D 12 ? "FAT12 " : "FAT16 ", 8); bootsector->magic[0]=3D0x55; bootsector->magic[1]=3D0xaa; =20 return 0; --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487871169602.4307304620237; Mon, 22 May 2017 14:17:51 -0700 (PDT) Received: from localhost ([::1]:44942 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCui5-0003bI-PZ for importer@patchew.org; Mon, 22 May 2017 17:17:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007dk-7B for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCucn-00007t-PP for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:2209) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuck-0008WK-7Y; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 6E5742003BE; Mon, 22 May 2017 23:12:16 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:11:59 +0200 Message-Id: <20170522211205.14265-8-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" readdir() doesn't always return . and .. entries at first and in that order. This leads to not creating them at first in the directory, which raises some errors on file system checking utilities like MS-DOS Scandisk. Specification: "FAT: General overview of on-disk format" v1.03, page 25 Fixes: https://bugs.launchpad.net/qemu/+bug/1599539 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index c1034cdd1f..d4664c531b 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -728,6 +728,12 @@ static int read_directory(BDRVVVFATState* s, int mappi= ng_index) i =3D mapping->info.dir.first_dir_index =3D first_cluster =3D=3D 0 ? 0 : s->directory.next; =20 + if (first_cluster !=3D 0) { + /* create the top entries of a subdirectory */ + (void)create_short_and_long_name(s, i, ".", 1); + (void)create_short_and_long_name(s, i, "..", 1); + } + /* actually read the directory, and allocate the mappings */ while((entry=3Dreaddir(dir))) { unsigned int length=3Dstrlen(dirname)+2+strlen(entry->d_name); @@ -749,8 +755,11 @@ static int read_directory(BDRVVVFATState* s, int mappi= ng_index) } =20 /* create directory entry for this file */ - direntry=3Dcreate_short_and_long_name(s, i, entry->d_name, - is_dot || is_dotdot); + if (!is_dot && !is_dotdot) { + direntry =3D create_short_and_long_name(s, i, entry->d_name, 0= ); + } else { + direntry =3D array_get(&(s->directory), is_dot ? i : i + 1); + } direntry->attributes=3D(S_ISDIR(st.st_mode)?0x10:0x20); direntry->reserved[0]=3Ddirentry->reserved[1]=3D0; direntry->ctime=3Dfat_datetime(st.st_ctime,1); --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487708994165.47384829024384; Mon, 22 May 2017 14:15:08 -0700 (PDT) Received: from localhost ([::1]:44929 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCufS-0001KH-HJ for importer@patchew.org; Mon, 22 May 2017 17:15:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37298) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuco-0007dP-Lk for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCucn-00007Y-Ie for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:22 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36938) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCucj-0008WH-Uz; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id CE1B12003F2; Mon, 22 May 2017 23:12:16 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:00 +0200 Message-Id: <20170522211205.14265-9-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Assume that input filename is encoded as UTF-8, so correctly create UTF-16 = encoding. Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d4664c531b..d34241da17 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -425,28 +425,19 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int= heads, int secs) =20 /* direntry functions */ =20 -/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next mult= iple of 26 */ -static inline int short2long_name(char* dest,const char* src) +static direntry_t *create_long_filename(BDRVVVFATState *s, const char *fil= ename) { - int i; - int len; - for(i=3D0;i<129 && src[i];i++) { - dest[2*i]=3Dsrc[i]; - dest[2*i+1]=3D0; + int number_of_entries, i; + glong length; + direntry_t *entry; + + gunichar2 *longname =3D g_utf8_to_utf16(filename, -1, NULL, &length, N= ULL); + if (!longname) { + fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename); + return NULL; } - len=3D2*i; - dest[2*i]=3Ddest[2*i+1]=3D0; - for(i=3D2*i+2;(i%26);i++) - dest[i]=3D0xff; - return len; -} =20 -static inline direntry_t* create_long_filename(BDRVVVFATState* s,const cha= r* filename) -{ - char buffer[258]; - int length=3Dshort2long_name(buffer,filename), - number_of_entries=3D(length+25)/26,i; - direntry_t* entry; + number_of_entries =3D (length * 2 + 25) / 26; =20 for(i=3D0;idirectory)); @@ -461,8 +452,15 @@ static inline direntry_t* create_long_filename(BDRVVVF= ATState* s,const char* fil else if(offset<22) offset=3D14+offset-10; else offset=3D28+offset-22; entry=3Darray_get(&(s->directory),s->directory.next-1-(i/26)); - entry->name[offset]=3Dbuffer[i]; + if (i >=3D 2 * length + 2) { + entry->name[offset] =3D 0xff; + } else if (i % 2 =3D=3D 0) { + entry->name[offset] =3D longname[i / 2] & 0xff; + } else { + entry->name[offset] =3D longname[i / 2] >> 8; + } } + g_free(longname); return array_get(&(s->directory),s->directory.next-number_of_entries); } =20 --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495488232018206.89343246551664; Mon, 22 May 2017 14:23:52 -0700 (PDT) Received: from localhost ([::1]:44986 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCunu-0008S7-LN for importer@patchew.org; Mon, 22 May 2017 17:23:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37379) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucq-0007eg-2P for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008r-Ko for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:2238) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuck-00004q-I7; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 368D52003F9; Mon, 22 May 2017 23:12:17 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:01 +0200 Message-Id: <20170522211205.14265-10-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short names for non-ASCII filenames X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" More specifically, create short name from filename and change blacklist of invalid chars to whitelist of valid chars. Windows 9x also now correctly see long file names of filenames containing a= space, but Scandisk still complains about mismatch between SFN and LFN. Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 105 ++++++++++++++++++++++++++++++++++++++++++------------= ---- 1 file changed, 77 insertions(+), 28 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d34241da17..3cb65493cd 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -516,6 +516,81 @@ static void set_begin_of_direntry(direntry_t* direntry= , uint32_t begin) direntry->begin_hi =3D cpu_to_le16((begin >> 16) & 0xffff); } =20 +static uint8_t to_valid_short_char(gunichar c) +{ + c =3D g_unichar_toupper(c); + if ((c >=3D '0' && c <=3D '9') || + (c >=3D 'A' && c <=3D 'Z') || + strchr("$%'-_@~`!(){}^#&", c) !=3D 0) { + return c; + } else { + return 0; + } +} + +static direntry_t *create_short_filename(BDRVVVFATState *s, + const char *filename) +{ + int i, j =3D 0; + direntry_t *entry =3D array_get_next(&(s->directory)); + const gchar *p, *last_dot =3D NULL; + gunichar c; + bool lossy_conversion =3D false; + char tail[11]; + + if (!entry) { + return NULL; + } + memset(entry->name, 0x20, sizeof(entry->name)); + + /* copy filename and search last dot */ + for (p =3D filename; ; p =3D g_utf8_next_char(p)) { + c =3D g_utf8_get_char(p); + if (c =3D=3D '\0') { + break; + } else if (c =3D=3D '.') { + if (j =3D=3D 0) { + /* '.' at start of filename */ + lossy_conversion =3D true; + } else { + if (last_dot) { + lossy_conversion =3D true; + } + last_dot =3D p; + } + } else if (!last_dot) { + /* first part of the name; copy it */ + uint8_t v =3D to_valid_short_char(c); + if (j < 8 && v) { + entry->name[j++] =3D v; + } else { + lossy_conversion =3D true; + } + } + } + + /* copy extension (if any) */ + if (last_dot) { + j =3D 0; + for (p =3D g_utf8_next_char(last_dot); ; p =3D g_utf8_next_char(p)= ) { + c =3D g_utf8_get_char(p); + if (c =3D=3D '\0') { + break; + } else { + /* extension; copy it */ + uint8_t v =3D to_valid_short_char(c); + if (j < 3 && v) { + entry->name[8 + (j++)] =3D v; + } else { + lossy_conversion =3D true; + } + } + } + } + (void)lossy_conversion; + return entry; +} + /* fat functions */ =20 static inline uint8_t fat_chksum(const direntry_t* entry) @@ -614,7 +689,7 @@ static inline void init_fat(BDRVVVFATState* s) static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, unsigned int directory_start, const char* filename, int is_dot) { - int i,j,long_index=3Ds->directory.next; + int long_index =3D s->directory.next; direntry_t* entry =3D NULL; direntry_t* entry_long =3D NULL; =20 @@ -626,33 +701,7 @@ static inline direntry_t* create_short_and_long_name(B= DRVVVFATState* s, } =20 entry_long=3Dcreate_long_filename(s,filename); - - i =3D strlen(filename); - for(j =3D i - 1; j>0 && filename[j]!=3D'.';j--); - if (j > 0) - i =3D (j > 8 ? 8 : j); - else if (i > 8) - i =3D 8; - - entry=3Darray_get_next(&(s->directory)); - memset(entry->name, 0x20, sizeof(entry->name)); - memcpy(entry->name, filename, i); - - if (j > 0) { - for (i =3D 0; i < 3 && filename[j + 1 + i]; i++) { - entry->name[8 + i] =3D filename[j + 1 + i]; - } - } - - /* upcase & remove unwanted characters */ - for(i=3D10;i>=3D0;i--) { - if(i=3D=3D10 || i=3D=3D7) for(;i>0 && entry->name[i]=3D=3D' ';i--); - if(entry->name[i]<=3D' ' || entry->name[i]>0x7f - || strchr(".*?<>|\":/\\[];,+=3D'",entry->name[i])) - entry->name[i]=3D'_'; - else if(entry->name[i]>=3D'a' && entry->name[i]<=3D'z') - entry->name[i]+=3D'A'-'a'; - } + entry =3D create_short_filename(s, filename); =20 /* mangle duplicates */ while(1) { --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 149548800840246.6884374440117; Mon, 22 May 2017 14:20:08 -0700 (PDT) Received: from localhost ([::1]:44955 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCukI-0005SI-US for importer@patchew.org; Mon, 22 May 2017 17:20:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37354) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007eE-Mw for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008d-I8 for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:36990) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCuck-00004u-M1; Mon, 22 May 2017 17:12:18 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 912072003FC; Mon, 22 May 2017 23:12:17 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:02 +0200 Message-Id: <20170522211205.14265-11-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" More specifically: - try without numeric-tail only if LFN didn't have invalid short chars - start at ~1 (instead of ~0) - handle case if numeric tail is more than one char (ie > 10) Windows 9x Scandisk doesn't see anymore mismatches between short file names= and long file names for non-ASCII filenames. Specification: "FAT: General overview of on-disk format" v1.03, page 31 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 62 ++++++++++++++++++++++++++++---------------------------= ---- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 3cb65493cd..414bca6dee 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -529,7 +529,8 @@ static uint8_t to_valid_short_char(gunichar c) } =20 static direntry_t *create_short_filename(BDRVVVFATState *s, - const char *filename) + const char *filename, + unsigned int directory_start) { int i, j =3D 0; direntry_t *entry =3D array_get_next(&(s->directory)); @@ -587,8 +588,32 @@ static direntry_t *create_short_filename(BDRVVVFATStat= e *s, } } } - (void)lossy_conversion; - return entry; + + /* numeric-tail generation */ + for (j =3D 0; j < 8; j++) { + if (entry->name[j] =3D=3D ' ') { + break; + } + } + for (i =3D lossy_conversion ? 1 : 0; i < 999999; i++) { + direntry_t *entry1; + if (i > 0) { + int len =3D sprintf(tail, "~%d", i); + memcpy(entry->name + MIN(j, 8 - len), tail, len); + } + for (entry1 =3D array_get(&(s->directory), directory_start); + entry1 < entry; entry1++) { + if (!is_long_name(entry1) && + !memcmp(entry1->name, entry->name, 11)) { + break; /* found dupe */ + } + } + if (entry1 =3D=3D entry) { + /* no dupe found */ + return entry; + } + } + return NULL; } =20 /* fat functions */ @@ -701,36 +726,7 @@ static inline direntry_t* create_short_and_long_name(B= DRVVVFATState* s, } =20 entry_long=3Dcreate_long_filename(s,filename); - entry =3D create_short_filename(s, filename); - - /* mangle duplicates */ - while(1) { - direntry_t* entry1=3Darray_get(&(s->directory),directory_start); - int j; - - for(;entry1name,entry->name,1= 1)) - break; /* found dupe */ - if(entry1=3D=3Dentry) /* no dupe found */ - break; - - /* use all 8 characters of name */ - if(entry->name[7]=3D=3D' ') { - int j; - for(j=3D6;j>0 && entry->name[j]=3D=3D' ';j--) - entry->name[j]=3D'~'; - } - - /* increment number */ - for(j=3D7;j>0 && entry->name[j]=3D=3D'9';j--) - entry->name[j]=3D'0'; - if(j>0) { - if(entry->name[j]<'0' || entry->name[j]>'9') - entry->name[j]=3D'0'; - else - entry->name[j]++; - } - } + entry =3D create_short_filename(s, filename, directory_start); =20 /* calculate checksum; propagate to long name */ if(entry_long) { --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487822972802.5320802439389; Mon, 22 May 2017 14:17:02 -0700 (PDT) Received: from localhost ([::1]:44939 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuhI-0002te-Et for importer@patchew.org; Mon, 22 May 2017 17:17:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucq-0007fl-Px for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCucp-00009d-Gt for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:37025) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCucl-00005J-2Z; Mon, 22 May 2017 17:12:19 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id F11E2200400; Mon, 22 May 2017 23:12:17 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:03 +0200 Message-Id: <20170522211205.14265-12-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" FAT12/FAT16 root directory is two sectors in size, which allows only 512 di= rectory entries. Prevent QEMU startup if too much files exist, instead of overflowing root d= irectory. Also introduce variable root_entries, which will be required for FAT32. Fixes: https://bugs.launchpad.net/qemu/+bug/1599539/comments/4 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 414bca6dee..5376659010 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -338,8 +338,9 @@ typedef struct BDRVVVFATState { unsigned int cluster_size; unsigned int sectors_per_cluster; unsigned int sectors_per_fat; - unsigned int sectors_of_root_directory; uint32_t last_cluster_of_root_directory; + /* how many entries are available in root directory (0 for FAT32) */ + uint16_t root_entries; uint32_t sector_count; /* total number of sectors of the partition */ uint32_t cluster_count; /* total number of clusters of this partition = */ uint32_t max_fat_value; @@ -786,6 +787,12 @@ static int read_directory(BDRVVVFATState* s, int mappi= ng_index) int is_dot=3D!strcmp(entry->d_name,"."); int is_dotdot=3D!strcmp(entry->d_name,".."); =20 + if (first_cluster =3D=3D 0 && s->directory.next >=3D s->root_entri= es - 1) { + fprintf(stderr, "Too many entries in root directory\n"); + closedir(dir); + return -2; + } + if(first_cluster =3D=3D 0 && (is_dotdot || is_dot)) continue; =20 @@ -859,15 +866,15 @@ static int read_directory(BDRVVVFATState* s, int mapp= ing_index) memset(direntry,0,sizeof(direntry_t)); } =20 -/* TODO: if there are more entries, bootsector has to be adjusted! */ -#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster) - if (mapping_index =3D=3D 0 && s->directory.next < ROOT_ENTRIES) { + if (s->fat_type !=3D 32 && + mapping_index =3D=3D 0 && + s->directory.next < s->root_entries) { /* root directory */ int cur =3D s->directory.next; - array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); - s->directory.next =3D ROOT_ENTRIES; + array_ensure_allocated(&(s->directory), s->root_entries - 1); + s->directory.next =3D s->root_entries; memset(array_get(&(s->directory), cur), 0, - (ROOT_ENTRIES - cur) * sizeof(direntry_t)); + (s->root_entries - cur) * sizeof(direntry_t)); } =20 /* re-get the mapping, since s->mapping was possibly realloc()ed */ @@ -932,6 +939,8 @@ static int init_directories(BDRVVVFATState* s, /* Now build FAT, and write back information into directory */ init_fat(s); =20 + /* TODO: if there are more entries, bootsector has to be adjusted! */ + s->root_entries =3D 0x02 * 0x10 * s->sectors_per_cluster; s->cluster_count=3Dsector2cluster(s, s->sector_count); =20 mapping =3D array_get_next(&(s->mapping)); @@ -1000,7 +1009,6 @@ static int init_directories(BDRVVVFATState* s, } =20 mapping =3D array_get(&(s->mapping), 0); - s->sectors_of_root_directory =3D mapping->end * s->sectors_per_cluster; s->last_cluster_of_root_directory =3D mapping->end; =20 /* the FAT signature */ @@ -1019,7 +1027,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->sectors_per_cluster=3Ds->sectors_per_cluster; bootsector->reserved_sectors=3Dcpu_to_le16(1); bootsector->number_of_fats=3D0x2; /* number of FATs */ - bootsector->root_entries=3Dcpu_to_le16(s->sectors_of_root_directory*0x= 10); + bootsector->root_entries =3D cpu_to_le16(s->root_entries); bootsector->total_sectors16=3Ds->sector_count>0xffff?0:cpu_to_le16(s->= sector_count); /* media descriptor: hard disk=3D0xf8, floppy=3D0xf0 */ bootsector->media_type =3D (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0); --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487665777830.4906632168278; Mon, 22 May 2017 14:14:25 -0700 (PDT) Received: from localhost ([::1]:44925 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuek-0000kA-A2 for importer@patchew.org; Mon, 22 May 2017 17:14:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37324) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007dl-7R for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008G-4I for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([212.27.42.2]:37038) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCucl-00005Z-GU; Mon, 22 May 2017 17:12:19 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 603CD2003FA; Mon, 22 May 2017 23:12:18 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:04 +0200 Message-Id: <20170522211205.14265-13-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.2 Subject: [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Specification: "FAT: General overview of on-disk format" v1.03, page 23 Signed-off-by: Herv=C3=A9 Poussineau --- block/vvfat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 5376659010..53e8faa54c 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -590,6 +590,10 @@ static direntry_t *create_short_filename(BDRVVVFATStat= e *s, } } =20 + if (entry->name[0] =3D=3D 0xe5) { + entry->name[0] =3D 0x05; + } + /* numeric-tail generation */ for (j =3D 0; j < 8; j++) { if (entry->name[j] =3D=3D ' ') { @@ -710,8 +714,6 @@ static inline void init_fat(BDRVVVFATState* s) =20 } =20 -/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */ -/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, unsigned int directory_start, const char* filename, int is_dot) { @@ -1744,6 +1746,9 @@ static int parse_short_name(BDRVVVFATState* s, } else lfn->name[i + j + 1] =3D '\0'; =20 + if (lfn->name[0] =3D=3D 0x05) { + lfn->name[0] =3D 0xe5; + } lfn->len =3D strlen((char*)lfn->name); =20 return 0; --=20 2.11.0 From nobody Sun May 5 12:37:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495487840402286.8638578903682; Mon, 22 May 2017 14:17:20 -0700 (PDT) Received: from localhost ([::1]:44941 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCuhb-00038y-3C for importer@patchew.org; Mon, 22 May 2017 17:17:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37344) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCucp-0007e6-J4 for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCuco-00008i-JN for qemu-devel@nongnu.org; Mon, 22 May 2017 17:12:23 -0400 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:2349) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dCucm-00005s-64; Mon, 22 May 2017 17:12:20 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id C7A212002E6; Mon, 22 May 2017 23:12:18 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 23:12:05 +0200 Message-Id: <20170522211205.14265-14-hpoussin@reactos.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170522211205.14265-1-hpoussin@reactos.org> References: <20170522211205.14265-1-hpoussin@reactos.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1' X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" According to specification: "'MSWIN4.1' is the recommanded setting, because it is the setting least lik= ely to cause compatibility problems. If you want to put something else in here, that is your option, but the result may be that some FAT drivers might not recognize the volume." Specification: "FAT: General overview of on-disk format" v1.03, page 9 Signed-off-by: Herv=C3=A9 Poussineau Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- block/vvfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index 53e8faa54c..1f7f46ecea 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->jump[0]=3D0xeb; bootsector->jump[1]=3D0x3e; bootsector->jump[2]=3D0x90; - memcpy(bootsector->name,"QEMU ",8); + memcpy(bootsector->name, "MSWIN4.1", 8); bootsector->sector_size=3Dcpu_to_le16(0x200); bootsector->sectors_per_cluster=3Ds->sectors_per_cluster; bootsector->reserved_sectors=3Dcpu_to_le16(1); --=20 2.11.0