exfat: use diff structs 4 vol labels and filenames

... and rename the structs to reflect this.

* Volume labels contain up to 11 uint16s (11 2-byte UTF-16 characters).
* Filenames are packed into 1 to 17 structs of 15 uint16s each (for a total
  of 255 2-byte UTF-16 characters).
* Use 2 different packed structs in the exfat_entry union (same bytes, accessed
  with different structs) to access these 2 things.
* Remove a check that assumed the length returned the number of 2-byte UTF-16
  characters, i.e. the number of uint16s the string uses. It doesn't, it
  returns the number of characters contained in the string which might be 2 or
  4-bytes wide. We're doing the conversion wrong for 4-byte UTF-16 characters
  anyway, more on that later.
This commit is contained in:
John Scipione 2014-02-11 13:13:53 -05:00
parent 675878fcfe
commit 5b10d763d0
3 changed files with 12 additions and 13 deletions

View File

@ -208,9 +208,9 @@ DirectoryIterator::_GetNext(uchar* name, size_t* _nameLength, ino_t* _id,
visitor->VisitFileInfo(fCurrent);
} else if (fCurrent->type == EXFAT_ENTRY_TYPE_FILENAME) {
TRACE("DirectoryIterator::_GetNext() Filename\n");
memcpy((uint8*)name + nameIndex, fCurrent->label.name,
sizeof(fCurrent->label.name));
nameIndex += sizeof(fCurrent->label.name);
memcpy((uint8*)name + nameIndex, fCurrent->file_name.name,
sizeof(fCurrent->file_name.name));
nameIndex += sizeof(fCurrent->file_name.name);
name[nameIndex] = '\0';
chunkCount--;
if (visitor != NULL)

View File

@ -30,14 +30,9 @@ get_volume_name(struct exfat_entry* entry, char* name, size_t length)
if (entry->type == EXFAT_ENTRY_TYPE_NOT_IN_USE)
name = "";
else if (entry->type == EXFAT_ENTRY_TYPE_LABEL) {
// UCS-2 can encode codepoints in the range U+0000 to U+FFFF
// UTF-8 needs at most 3 bytes to encode values in this range
size_t utf8NameLength = entry->label.length * 3;
if (length < utf8NameLength)
return B_NAME_TOO_LONG;
status_t result = unicode_to_utf8((const uchar*)entry->label.name,
entry->label.length * 2, (uint8*)name, &utf8NameLength);
status_t result
= unicode_to_utf8((const uchar*)entry->volume_label.name,
entry->volume_label.length * 2, (uint8*)name, &length);
if (result != B_OK)
return result;
} else

View File

@ -104,14 +104,14 @@ struct exfat_entry {
uint8 length;
uint16 name[11];
uint8 reserved[8];
} _PACKED label;
} _PACKED volume_label;
struct {
uint8 chunkCount;
uint16 checksum;
uint16 flags;
uint8 guid[16];
uint8 reserved[10];
} _PACKED guid;
} _PACKED volume_guid;
struct {
uint8 reserved[3];
uint32 checksum;
@ -171,6 +171,10 @@ struct exfat_entry {
uint64 Size() const
{ return B_LENDIAN_TO_HOST_INT64(size1); }
} _PACKED file_info;
struct {
uint8 flags;
uint16 name[15];
} _PACKED file_name;
};
} _PACKED;