diff options
author | Hervé Poussineau <hpoussin@reactos.org> | 2017-05-22 23:12:00 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-07-10 13:18:05 +0200 |
commit | 09ec4119fb5a48f6783c23e275e698d977a11ca9 (patch) | |
tree | b445c75e472d1726d7e697e858b1fdf247207937 /block | |
parent | f82d92bb028a1d674bab4ccc7e6cde6c04956230 (diff) |
vvfat: correctly create long names for non-ASCII filenames
Assume that input filename is encoded as UTF-8, so correctly create UTF-16 encoding.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/vvfat.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/block/vvfat.c b/block/vvfat.c index 0c6d0f407f..c52c9ba914 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -424,28 +424,19 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs) /* direntry functions */ -/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */ -static inline int short2long_name(char* dest,const char* src) +static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename) { - int i; - int len; - for(i=0;i<129 && src[i];i++) { - dest[2*i]=src[i]; - dest[2*i+1]=0; + int number_of_entries, i; + glong length; + direntry_t *entry; + + gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL); + if (!longname) { + fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename); + return NULL; } - len=2*i; - dest[2*i]=dest[2*i+1]=0; - for(i=2*i+2;(i%26);i++) - dest[i]=0xff; - return len; -} -static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename) -{ - char buffer[258]; - int length=short2long_name(buffer,filename), - number_of_entries=(length+25)/26,i; - direntry_t* entry; + number_of_entries = (length * 2 + 25) / 26; for(i=0;i<number_of_entries;i++) { entry=array_get_next(&(s->directory)); @@ -460,8 +451,15 @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil else if(offset<22) offset=14+offset-10; else offset=28+offset-22; entry=array_get(&(s->directory),s->directory.next-1-(i/26)); - entry->name[offset]=buffer[i]; + if (i >= 2 * length + 2) { + entry->name[offset] = 0xff; + } else if (i % 2 == 0) { + entry->name[offset] = longname[i / 2] & 0xff; + } else { + entry->name[offset] = longname[i / 2] >> 8; + } } + g_free(longname); return array_get(&(s->directory),s->directory.next-number_of_entries); } |