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:
@@ -208,9 +208,9 @@ DirectoryIterator::_GetNext(uchar* name, size_t* _nameLength, ino_t* _id,
|
|||||||
visitor->VisitFileInfo(fCurrent);
|
visitor->VisitFileInfo(fCurrent);
|
||||||
} else if (fCurrent->type == EXFAT_ENTRY_TYPE_FILENAME) {
|
} else if (fCurrent->type == EXFAT_ENTRY_TYPE_FILENAME) {
|
||||||
TRACE("DirectoryIterator::_GetNext() Filename\n");
|
TRACE("DirectoryIterator::_GetNext() Filename\n");
|
||||||
memcpy((uint8*)name + nameIndex, fCurrent->label.name,
|
memcpy((uint8*)name + nameIndex, fCurrent->file_name.name,
|
||||||
sizeof(fCurrent->label.name));
|
sizeof(fCurrent->file_name.name));
|
||||||
nameIndex += sizeof(fCurrent->label.name);
|
nameIndex += sizeof(fCurrent->file_name.name);
|
||||||
name[nameIndex] = '\0';
|
name[nameIndex] = '\0';
|
||||||
chunkCount--;
|
chunkCount--;
|
||||||
if (visitor != NULL)
|
if (visitor != NULL)
|
||||||
|
|||||||
@@ -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)
|
if (entry->type == EXFAT_ENTRY_TYPE_NOT_IN_USE)
|
||||||
name = "";
|
name = "";
|
||||||
else if (entry->type == EXFAT_ENTRY_TYPE_LABEL) {
|
else if (entry->type == EXFAT_ENTRY_TYPE_LABEL) {
|
||||||
// UCS-2 can encode codepoints in the range U+0000 to U+FFFF
|
status_t result
|
||||||
// UTF-8 needs at most 3 bytes to encode values in this range
|
= unicode_to_utf8((const uchar*)entry->volume_label.name,
|
||||||
size_t utf8NameLength = entry->label.length * 3;
|
entry->volume_label.length * 2, (uint8*)name, &length);
|
||||||
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);
|
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
} else
|
} else
|
||||||
|
|||||||
@@ -104,14 +104,14 @@ struct exfat_entry {
|
|||||||
uint8 length;
|
uint8 length;
|
||||||
uint16 name[11];
|
uint16 name[11];
|
||||||
uint8 reserved[8];
|
uint8 reserved[8];
|
||||||
} _PACKED label;
|
} _PACKED volume_label;
|
||||||
struct {
|
struct {
|
||||||
uint8 chunkCount;
|
uint8 chunkCount;
|
||||||
uint16 checksum;
|
uint16 checksum;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
uint8 guid[16];
|
uint8 guid[16];
|
||||||
uint8 reserved[10];
|
uint8 reserved[10];
|
||||||
} _PACKED guid;
|
} _PACKED volume_guid;
|
||||||
struct {
|
struct {
|
||||||
uint8 reserved[3];
|
uint8 reserved[3];
|
||||||
uint32 checksum;
|
uint32 checksum;
|
||||||
@@ -171,6 +171,10 @@ struct exfat_entry {
|
|||||||
uint64 Size() const
|
uint64 Size() const
|
||||||
{ return B_LENDIAN_TO_HOST_INT64(size1); }
|
{ return B_LENDIAN_TO_HOST_INT64(size1); }
|
||||||
} _PACKED file_info;
|
} _PACKED file_info;
|
||||||
|
struct {
|
||||||
|
uint8 flags;
|
||||||
|
uint16 name[15];
|
||||||
|
} _PACKED file_name;
|
||||||
};
|
};
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user