fat: correctly read lowercase 8.3 filenames
Historically, FAT stored filenames as uppercase. Modern windows versions will however be case-preserving. As a special case, all-uppercase files from old FAT filesystems will be converted to all-lowercase. There are two flags (one for filename and one for extension) indicating that this should be done. We did not make the distinction between these two flags when reading a filename. We still don't set the flags properly when writing files, but we always provide a long file name (even if the name would fit in the 8.3 pattern for a short one, so when reading back our own entries, we should always use the long filename and be safe. Change-Id: I1618a5be22705de3a06534442b62074445069764
This commit is contained in:
committed by
waddlesplash
parent
e5c4ce4f67
commit
08021a3beb
@@ -1507,7 +1507,7 @@ status_t generate_short_name(const uchar *name, const uchar *uni,
|
||||
/* called to convert a short ms-dos filename to utf8.
|
||||
XXX: encoding is assumed to be standard US code page, never shift-JIS
|
||||
*/
|
||||
status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len, bool toLower)
|
||||
status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len, uint8 toLower)
|
||||
{
|
||||
uchar normalized[8+1+3+1];
|
||||
int32 i, pos;
|
||||
@@ -1516,16 +1516,19 @@ status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len, bool toLower)
|
||||
|
||||
pos = 0;
|
||||
for (i=0;i<8;i++) {
|
||||
if (msdos[i] == ' ') break;
|
||||
if (msdos[i] == ' ')
|
||||
break;
|
||||
normalized[pos++] = ((i == 0) && (msdos[i] == 5)) ? 0xe5 :
|
||||
(toLower ? tolower(msdos[i]) : msdos[i]);
|
||||
((toLower & 0x08) ? tolower(msdos[i]) : msdos[i]);
|
||||
}
|
||||
|
||||
if (msdos[8] != ' ') {
|
||||
normalized[pos++] = '.';
|
||||
for (i=8;i<11;i++) {
|
||||
if (msdos[i] == ' ') break;
|
||||
normalized[pos++] = (toLower ? tolower(msdos[i]) : msdos[i]);
|
||||
if (msdos[i] == ' ')
|
||||
break;
|
||||
normalized[pos++]
|
||||
= ((toLower & 0x10) ? tolower(msdos[i]) : msdos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1535,20 +1538,26 @@ status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len, bool toLower)
|
||||
(char *)utf8, (int32 *)&utf8len);
|
||||
}
|
||||
|
||||
bool requires_munged_short_name(const uchar *utf8name, const uchar nshort[11], int encoding)
|
||||
bool requires_munged_short_name(const uchar *utf8name, const uchar nshort[11],
|
||||
int encoding)
|
||||
{
|
||||
int leading = 0;
|
||||
int trailing = 0;
|
||||
int i, len;
|
||||
|
||||
if (encoding != MS_DOS_CONVERSION) return true;
|
||||
if (encoding != MS_DOS_CONVERSION)
|
||||
return true;
|
||||
|
||||
for ( ; *utf8name != 0; utf8name++) {
|
||||
if (!BEGINS_UTF8CHAR(*utf8name)) continue;
|
||||
if (*utf8name == '.') break;
|
||||
if (!BEGINS_UTF8CHAR(*utf8name))
|
||||
continue;
|
||||
if (*utf8name == '.')
|
||||
break;
|
||||
leading++;
|
||||
if (leading > 8) return true;
|
||||
if ((nshort[leading - 1] == '_') && (*utf8name != '_')) return true;
|
||||
if (leading > 8)
|
||||
return true;
|
||||
if ((nshort[leading - 1] == '_') && (*utf8name != '_'))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*utf8name != 0) {
|
||||
|
||||
@@ -22,7 +22,8 @@ status_t munge_short_name1(uchar nshort[11], int iteration, int encoding);
|
||||
status_t generate_short_name(const uchar *name, const uchar *uni,
|
||||
uint32 unilen, uchar nshort[11], int *encoding);
|
||||
|
||||
status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len, bool toLower);
|
||||
status_t msdos_to_utf8(uchar *msdos, uchar *utf8, uint32 utf8len,
|
||||
uint8 toLower);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user