exfat: Set the mountpoint to same as volume name
Fixes #10501 * update copyright headers, attribute to Haiku, Inc. add authors * volume_name gets filled out by a utility function in Utility.cpp * update exfat_entry - rename name_label to just label - adjust volume_label to have 11 uint16 chars plus 8 uint8 reserved - add guid partition info * Added a couple new entry type defines * fName is 34 bytes long which fits the 11 3-byte UTF-8 chars and a \0
This commit is contained in:
parent
c79381d32a
commit
762b846cf8
|
@ -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->name_label.name,
|
||||
sizeof(fCurrent->name_label.name));
|
||||
nameIndex += sizeof(fCurrent->name_label.name);
|
||||
memcpy((uint8*)name + nameIndex, fCurrent->label.name,
|
||||
sizeof(fCurrent->label.name));
|
||||
nameIndex += sizeof(fCurrent->label.name);
|
||||
name[nameIndex] = '\0';
|
||||
chunkCount--;
|
||||
if (visitor != NULL)
|
||||
|
|
|
@ -10,5 +10,6 @@ KernelAddon exfat :
|
|||
encodings.cpp
|
||||
Inode.cpp
|
||||
kernel_interface.cpp
|
||||
Utility.cpp
|
||||
Volume.cpp
|
||||
;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include "Utility.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Errors.h>
|
||||
|
||||
#include "encodings.h"
|
||||
|
||||
|
||||
status_t
|
||||
volume_name(struct exfat_entry* entry, char* _name)
|
||||
{
|
||||
if (entry == NULL || _name == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (entry->type == EXFAT_ENTRY_TYPE_NOT_IN_USE) {
|
||||
const char* untitled = "Untitled";
|
||||
size_t length = strlen(untitled);
|
||||
strncpy(_name, untitled, length);
|
||||
if (strlen(_name) < length)
|
||||
return B_NAME_TOO_LONG;
|
||||
} 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;
|
||||
memset(_name, 0, utf8NameLength + 1);
|
||||
// zero out the character array
|
||||
unicode_to_utf8((const uchar*)entry->label.name,
|
||||
entry->label.length * 2, (uint8*)_name, &utf8NameLength);
|
||||
if (strlen(_name) < utf8NameLength)
|
||||
return B_NAME_TOO_LONG;
|
||||
} else
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
return B_OK;
|
||||
}
|
|
@ -1,6 +1,12 @@
|
|||
/*
|
||||
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#ifndef UTILITY_H
|
||||
#define UTILITY_H
|
||||
|
@ -38,4 +44,17 @@ open_mode_to_access(int openMode)
|
|||
return R_OK | W_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! Reads the volume name from an exfat entry and writes it to \a _name
|
||||
as a UTF-8 char array. Writes "Untitled" The volume name is not set.
|
||||
\returns A status code.
|
||||
\retval B_OK Wrote the volume name successfully.
|
||||
\retval B_BAD_VALUE \a entry or \a _name was \c NULL.
|
||||
\retval B_NAME_NOT_FOUND Volume name was not found in this entry.
|
||||
\retval B_NAME_TOO_LONG The passed in _name wasn't long enough to
|
||||
fit the name.
|
||||
*/
|
||||
status_t volume_name(struct exfat_entry* entry, char* _name);
|
||||
|
||||
|
||||
#endif // UTILITY_H
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
/*
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
|
@ -11,6 +18,7 @@
|
|||
#include "Volume.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -22,8 +30,8 @@
|
|||
#include <util/AutoLock.h>
|
||||
|
||||
#include "CachedBlock.h"
|
||||
#include "encodings.h"
|
||||
#include "Inode.h"
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
//#define TRACE_EXFAT
|
||||
|
@ -222,11 +230,12 @@ bool
|
|||
LabelVisitor::VisitLabel(struct exfat_entry* entry)
|
||||
{
|
||||
TRACE("LabelVisitor::VisitLabel()\n");
|
||||
char utfName[30];
|
||||
size_t utfLength = 30;
|
||||
unicode_to_utf8((const uchar*)entry->name_label.name,
|
||||
entry->name_label.length * 2, (uint8*)utfName, &utfLength);
|
||||
fVolume->SetName(utfName);
|
||||
char name[34];
|
||||
status_t result = volume_name(entry, name);
|
||||
if (result != B_OK)
|
||||
return false;
|
||||
|
||||
fVolume->SetName(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
/*
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#ifndef VOLUME_H
|
||||
#define VOLUME_H
|
||||
|
@ -144,7 +151,9 @@ private:
|
|||
fs_volume* fFSVolume;
|
||||
int fDevice;
|
||||
exfat_super_block fSuperBlock;
|
||||
char fName[32];
|
||||
char fName[34];
|
||||
// Max number of bytes needed is (11 * 3) + 1 for the \0,
|
||||
// that is 11 UCS-2 characters converted to UTF-8.
|
||||
|
||||
uint16 fFlags;
|
||||
uint32 fBlockSize;
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
/*
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2014 Haiku, Inc. All Rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#ifndef EXFAT_H
|
||||
#define EXFAT_H
|
||||
|
@ -75,10 +81,12 @@ struct exfat_super_block {
|
|||
|
||||
#define EXFAT_SUPER_BLOCK_MAGIC "EXFAT "
|
||||
|
||||
#define EXFAT_ENTRY_TYPE_NOT_IN_USE 0x03
|
||||
#define EXFAT_ENTRY_TYPE_BITMAP 0x81
|
||||
#define EXFAT_ENTRY_TYPE_UPPERCASE 0x82
|
||||
#define EXFAT_ENTRY_TYPE_LABEL 0x83
|
||||
#define EXFAT_ENTRY_TYPE_FILE 0x85
|
||||
#define EXFAT_ENTRY_TYPE_GUID 0xa0
|
||||
#define EXFAT_ENTRY_TYPE_FILEINFO 0xc0
|
||||
#define EXFAT_ENTRY_TYPE_FILENAME 0xc1
|
||||
#define EXFAT_CLUSTER_END 0xffffffff
|
||||
|
@ -94,8 +102,16 @@ struct exfat_entry {
|
|||
union {
|
||||
struct {
|
||||
uint8 length;
|
||||
char name[30];
|
||||
} _PACKED name_label;
|
||||
uint16 name[11];
|
||||
uint8 reserved[8];
|
||||
} _PACKED label;
|
||||
struct {
|
||||
uint8 chunkCount;
|
||||
uint16 checksum;
|
||||
uint16 flags;
|
||||
uint8 guid[16];
|
||||
uint8 reserved[10];
|
||||
} _PACKED guid;
|
||||
struct {
|
||||
uint8 reserved[3];
|
||||
uint32 checksum;
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
/*
|
||||
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <fs_cache.h>
|
||||
#include <fs_info.h>
|
||||
|
@ -36,6 +46,7 @@
|
|||
|
||||
struct identify_cookie {
|
||||
exfat_super_block super_block;
|
||||
char name[34];
|
||||
};
|
||||
|
||||
|
||||
|
@ -66,15 +77,45 @@ iterative_io_finished_hook(void* cookie, io_request* request, status_t status,
|
|||
|
||||
|
||||
static float
|
||||
exfat_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||
exfat_identify_partition(int fd, partition_data* _partition, void** _cookie)
|
||||
{
|
||||
exfat_super_block superBlock;
|
||||
struct exfat_super_block superBlock;
|
||||
status_t status = Volume::Identify(fd, &superBlock);
|
||||
if (status != B_OK)
|
||||
return -1;
|
||||
|
||||
identify_cookie *cookie = new identify_cookie;
|
||||
identify_cookie* cookie = new (std::nothrow)identify_cookie;
|
||||
if (cookie == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy(&cookie->super_block, &superBlock, sizeof(exfat_super_block));
|
||||
memset(cookie->name, 0, 34);
|
||||
// zero out volume name
|
||||
|
||||
uint32 rootDirCluster = superBlock.RootDirCluster();
|
||||
uint32 blockSize = 1 << superBlock.BlockShift();
|
||||
uint32 clusterSize = blockSize << superBlock.BlocksPerClusterShift();
|
||||
uint64 rootDirectoryOffset = (uint64)(EXFAT_SUPER_BLOCK_OFFSET
|
||||
+ superBlock.FirstDataBlock() * blockSize
|
||||
+ (rootDirCluster - 2) * clusterSize);
|
||||
struct exfat_entry entry;
|
||||
size_t entrySize = sizeof(struct exfat_entry);
|
||||
for (uint32 i = 0; read_pos(fd, rootDirectoryOffset + i * entrySize,
|
||||
&entry, entrySize) == (ssize_t)entrySize; i++) {
|
||||
if (entry.type == EXFAT_ENTRY_TYPE_NOT_IN_USE
|
||||
|| entry.type == EXFAT_ENTRY_TYPE_LABEL) {
|
||||
if (volume_name(&entry, cookie->name) != B_OK) {
|
||||
delete cookie;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie->name[0] == '\0') {
|
||||
delete cookie;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*_cookie = cookie;
|
||||
return 0.8f;
|
||||
|
@ -82,21 +123,18 @@ exfat_identify_partition(int fd, partition_data *partition, void **_cookie)
|
|||
|
||||
|
||||
static status_t
|
||||
exfat_scan_partition(int fd, partition_data *partition, void *_cookie)
|
||||
exfat_scan_partition(int fd, partition_data* _partition, void* _cookie)
|
||||
{
|
||||
identify_cookie *cookie = (identify_cookie *)_cookie;
|
||||
identify_cookie* cookie = (identify_cookie*)_cookie;
|
||||
|
||||
partition->status = B_PARTITION_VALID;
|
||||
partition->flags |= B_PARTITION_FILE_SYSTEM;
|
||||
partition->content_size = cookie->super_block.NumBlocks()
|
||||
_partition->status = B_PARTITION_VALID;
|
||||
_partition->flags |= B_PARTITION_FILE_SYSTEM;
|
||||
_partition->content_size = cookie->super_block.NumBlocks()
|
||||
<< cookie->super_block.BlockShift();
|
||||
partition->block_size = 1 << cookie->super_block.BlockShift();
|
||||
// TODO volume name isn't in the superblock
|
||||
partition->content_name = strdup(cookie->super_block.filesystem);
|
||||
if (partition->content_name == NULL)
|
||||
return B_NO_MEMORY;
|
||||
_partition->block_size = 1 << cookie->super_block.BlockShift();
|
||||
_partition->content_name = strdup(cookie->name);
|
||||
|
||||
return B_OK;
|
||||
return _partition->content_name != NULL ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue