mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-05-28 22:14:33 -04:00
Experimental Linux GUI based on web browser
This commit is contained in:
parent
7279ba9bc8
commit
43e8ec5785
158 changed files with 43670 additions and 0 deletions
68
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h
Normal file
68
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
byteorder.h (12.01.10)
|
||||
Endianness stuff. exFAT uses little-endian byte order.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef BYTEORDER_H_INCLUDED
|
||||
#define BYTEORDER_H_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct { uint16_t __u16; } le16_t;
|
||||
typedef struct { uint32_t __u32; } le32_t;
|
||||
typedef struct { uint64_t __u64; } le64_t;
|
||||
|
||||
#if EXFAT_BYTE_ORDER == EXFAT_LITTLE_ENDIAN
|
||||
|
||||
static inline uint16_t le16_to_cpu(le16_t v) { return v.__u16; }
|
||||
static inline uint32_t le32_to_cpu(le32_t v) { return v.__u32; }
|
||||
static inline uint64_t le64_to_cpu(le64_t v) { return v.__u64; }
|
||||
|
||||
static inline le16_t cpu_to_le16(uint16_t v) { le16_t t = {v}; return t; }
|
||||
static inline le32_t cpu_to_le32(uint32_t v) { le32_t t = {v}; return t; }
|
||||
static inline le64_t cpu_to_le64(uint64_t v) { le64_t t = {v}; return t; }
|
||||
|
||||
typedef size_t bitmap_t;
|
||||
|
||||
#elif EXFAT_BYTE_ORDER == EXFAT_BIG_ENDIAN
|
||||
|
||||
static inline uint16_t le16_to_cpu(le16_t v)
|
||||
{ return exfat_bswap16(v.__u16); }
|
||||
static inline uint32_t le32_to_cpu(le32_t v)
|
||||
{ return exfat_bswap32(v.__u32); }
|
||||
static inline uint64_t le64_to_cpu(le64_t v)
|
||||
{ return exfat_bswap64(v.__u64); }
|
||||
|
||||
static inline le16_t cpu_to_le16(uint16_t v)
|
||||
{ le16_t t = {exfat_bswap16(v)}; return t; }
|
||||
static inline le32_t cpu_to_le32(uint32_t v)
|
||||
{ le32_t t = {exfat_bswap32(v)}; return t; }
|
||||
static inline le64_t cpu_to_le64(uint64_t v)
|
||||
{ le64_t t = {exfat_bswap64(v)}; return t; }
|
||||
|
||||
typedef unsigned char bitmap_t;
|
||||
|
||||
#else
|
||||
#error Wow! You have a PDP machine?!
|
||||
#endif
|
||||
|
||||
#endif /* ifndef BYTEORDER_H_INCLUDED */
|
491
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c
Normal file
491
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c
Normal file
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
cluster.c (03.09.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Sector to absolute offset.
|
||||
*/
|
||||
static off_t s2o(const struct exfat* ef, off_t sector)
|
||||
{
|
||||
return sector << ef->sb->sector_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cluster to sector.
|
||||
*/
|
||||
static off_t c2s(const struct exfat* ef, cluster_t cluster)
|
||||
{
|
||||
if (cluster < EXFAT_FIRST_DATA_CLUSTER)
|
||||
exfat_bug("invalid cluster number %u", cluster);
|
||||
return le32_to_cpu(ef->sb->cluster_sector_start) +
|
||||
((off_t) (cluster - EXFAT_FIRST_DATA_CLUSTER) << ef->sb->spc_bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cluster to absolute offset.
|
||||
*/
|
||||
off_t exfat_c2o(const struct exfat* ef, cluster_t cluster)
|
||||
{
|
||||
return s2o(ef, c2s(ef, cluster));
|
||||
}
|
||||
|
||||
/*
|
||||
* Sector to cluster.
|
||||
*/
|
||||
static cluster_t s2c(const struct exfat* ef, off_t sector)
|
||||
{
|
||||
return ((sector - le32_to_cpu(ef->sb->cluster_sector_start)) >>
|
||||
ef->sb->spc_bits) + EXFAT_FIRST_DATA_CLUSTER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Size in bytes to size in clusters (rounded upwards).
|
||||
*/
|
||||
static uint32_t bytes2clusters(const struct exfat* ef, uint64_t bytes)
|
||||
{
|
||||
uint64_t cluster_size = CLUSTER_SIZE(*ef->sb);
|
||||
return DIV_ROUND_UP(bytes, cluster_size);
|
||||
}
|
||||
|
||||
cluster_t exfat_next_cluster(const struct exfat* ef,
|
||||
const struct exfat_node* node, cluster_t cluster)
|
||||
{
|
||||
le32_t next;
|
||||
off_t fat_offset;
|
||||
|
||||
if (cluster < EXFAT_FIRST_DATA_CLUSTER)
|
||||
exfat_bug("bad cluster 0x%x", cluster);
|
||||
|
||||
if (node->is_contiguous)
|
||||
return cluster + 1;
|
||||
fat_offset = s2o(ef, le32_to_cpu(ef->sb->fat_sector_start))
|
||||
+ cluster * sizeof(cluster_t);
|
||||
if (exfat_pread(ef->dev, &next, sizeof(next), fat_offset) < 0)
|
||||
return EXFAT_CLUSTER_BAD; /* the caller should handle this and print
|
||||
appropriate error message */
|
||||
return le32_to_cpu(next);
|
||||
}
|
||||
|
||||
cluster_t exfat_advance_cluster(const struct exfat* ef,
|
||||
struct exfat_node* node, uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (node->fptr_index > count)
|
||||
{
|
||||
node->fptr_index = 0;
|
||||
node->fptr_cluster = node->start_cluster;
|
||||
}
|
||||
|
||||
for (i = node->fptr_index; i < count; i++)
|
||||
{
|
||||
node->fptr_cluster = exfat_next_cluster(ef, node, node->fptr_cluster);
|
||||
if (CLUSTER_INVALID(*ef->sb, node->fptr_cluster))
|
||||
break; /* the caller should handle this and print appropriate
|
||||
error message */
|
||||
}
|
||||
node->fptr_index = count;
|
||||
return node->fptr_cluster;
|
||||
}
|
||||
|
||||
static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end)
|
||||
{
|
||||
const size_t start_index = start / sizeof(bitmap_t) / 8;
|
||||
const size_t end_index = DIV_ROUND_UP(end, sizeof(bitmap_t) * 8);
|
||||
size_t i;
|
||||
size_t start_bitindex;
|
||||
size_t end_bitindex;
|
||||
size_t c;
|
||||
|
||||
for (i = start_index; i < end_index; i++)
|
||||
{
|
||||
if (bitmap[i] == ~((bitmap_t) 0))
|
||||
continue;
|
||||
start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start);
|
||||
end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end);
|
||||
for (c = start_bitindex; c < end_bitindex; c++)
|
||||
if (BMAP_GET(bitmap, c) == 0)
|
||||
{
|
||||
BMAP_SET(bitmap, c);
|
||||
return c + EXFAT_FIRST_DATA_CLUSTER;
|
||||
}
|
||||
}
|
||||
return EXFAT_CLUSTER_END;
|
||||
}
|
||||
|
||||
static int flush_nodes(struct exfat* ef, struct exfat_node* node)
|
||||
{
|
||||
struct exfat_node* p;
|
||||
|
||||
for (p = node->child; p != NULL; p = p->next)
|
||||
{
|
||||
int rc = flush_nodes(ef, p);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
return exfat_flush_node(ef, node);
|
||||
}
|
||||
|
||||
int exfat_flush_nodes(struct exfat* ef)
|
||||
{
|
||||
return flush_nodes(ef, ef->root);
|
||||
}
|
||||
|
||||
int exfat_flush(struct exfat* ef)
|
||||
{
|
||||
if (ef->cmap.dirty)
|
||||
{
|
||||
if (exfat_pwrite(ef->dev, ef->cmap.chunk,
|
||||
BMAP_SIZE(ef->cmap.chunk_size),
|
||||
exfat_c2o(ef, ef->cmap.start_cluster)) < 0)
|
||||
{
|
||||
exfat_error("failed to write clusters bitmap");
|
||||
return -EIO;
|
||||
}
|
||||
ef->cmap.dirty = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool set_next_cluster(const struct exfat* ef, bool contiguous,
|
||||
cluster_t current, cluster_t next)
|
||||
{
|
||||
off_t fat_offset;
|
||||
le32_t next_le32;
|
||||
|
||||
if (contiguous)
|
||||
return true;
|
||||
fat_offset = s2o(ef, le32_to_cpu(ef->sb->fat_sector_start))
|
||||
+ current * sizeof(cluster_t);
|
||||
next_le32 = cpu_to_le32(next);
|
||||
if (exfat_pwrite(ef->dev, &next_le32, sizeof(next_le32), fat_offset) < 0)
|
||||
{
|
||||
exfat_error("failed to write the next cluster %#x after %#x", next,
|
||||
current);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static cluster_t allocate_cluster(struct exfat* ef, cluster_t hint)
|
||||
{
|
||||
cluster_t cluster;
|
||||
|
||||
hint -= EXFAT_FIRST_DATA_CLUSTER;
|
||||
if (hint >= ef->cmap.chunk_size)
|
||||
hint = 0;
|
||||
|
||||
cluster = find_bit_and_set(ef->cmap.chunk, hint, ef->cmap.chunk_size);
|
||||
if (cluster == EXFAT_CLUSTER_END)
|
||||
cluster = find_bit_and_set(ef->cmap.chunk, 0, hint);
|
||||
if (cluster == EXFAT_CLUSTER_END)
|
||||
{
|
||||
exfat_error("no free space left");
|
||||
return EXFAT_CLUSTER_END;
|
||||
}
|
||||
|
||||
ef->cmap.dirty = true;
|
||||
return cluster;
|
||||
}
|
||||
|
||||
static void free_cluster(struct exfat* ef, cluster_t cluster)
|
||||
{
|
||||
if (cluster - EXFAT_FIRST_DATA_CLUSTER >= ef->cmap.size)
|
||||
exfat_bug("caller must check cluster validity (%#x, %#x)", cluster,
|
||||
ef->cmap.size);
|
||||
|
||||
BMAP_CLR(ef->cmap.chunk, cluster - EXFAT_FIRST_DATA_CLUSTER);
|
||||
ef->cmap.dirty = true;
|
||||
}
|
||||
|
||||
static bool make_noncontiguous(const struct exfat* ef, cluster_t first,
|
||||
cluster_t last)
|
||||
{
|
||||
cluster_t c;
|
||||
|
||||
for (c = first; c < last; c++)
|
||||
if (!set_next_cluster(ef, false, c, c + 1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int shrink_file(struct exfat* ef, struct exfat_node* node,
|
||||
uint32_t current, uint32_t difference);
|
||||
|
||||
static int grow_file(struct exfat* ef, struct exfat_node* node,
|
||||
uint32_t current, uint32_t difference)
|
||||
{
|
||||
cluster_t previous;
|
||||
cluster_t next;
|
||||
uint32_t allocated = 0;
|
||||
|
||||
if (difference == 0)
|
||||
exfat_bug("zero clusters count passed");
|
||||
|
||||
if (node->start_cluster != EXFAT_CLUSTER_FREE)
|
||||
{
|
||||
/* get the last cluster of the file */
|
||||
previous = exfat_advance_cluster(ef, node, current - 1);
|
||||
if (CLUSTER_INVALID(*ef->sb, previous))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while growing", previous);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node->fptr_index != 0)
|
||||
exfat_bug("non-zero pointer index (%u)", node->fptr_index);
|
||||
/* file does not have clusters (i.e. is empty), allocate
|
||||
the first one for it */
|
||||
previous = allocate_cluster(ef, 0);
|
||||
if (CLUSTER_INVALID(*ef->sb, previous))
|
||||
return -ENOSPC;
|
||||
node->fptr_cluster = node->start_cluster = previous;
|
||||
allocated = 1;
|
||||
/* file consists of only one cluster, so it's contiguous */
|
||||
node->is_contiguous = true;
|
||||
}
|
||||
|
||||
while (allocated < difference)
|
||||
{
|
||||
next = allocate_cluster(ef, previous + 1);
|
||||
if (CLUSTER_INVALID(*ef->sb, next))
|
||||
{
|
||||
if (allocated != 0)
|
||||
shrink_file(ef, node, current + allocated, allocated);
|
||||
return -ENOSPC;
|
||||
}
|
||||
if (next != previous - 1 && node->is_contiguous)
|
||||
{
|
||||
/* it's a pity, but we are not able to keep the file contiguous
|
||||
anymore */
|
||||
if (!make_noncontiguous(ef, node->start_cluster, previous))
|
||||
return -EIO;
|
||||
node->is_contiguous = false;
|
||||
node->is_dirty = true;
|
||||
}
|
||||
if (!set_next_cluster(ef, node->is_contiguous, previous, next))
|
||||
return -EIO;
|
||||
previous = next;
|
||||
allocated++;
|
||||
}
|
||||
|
||||
if (!set_next_cluster(ef, node->is_contiguous, previous,
|
||||
EXFAT_CLUSTER_END))
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shrink_file(struct exfat* ef, struct exfat_node* node,
|
||||
uint32_t current, uint32_t difference)
|
||||
{
|
||||
cluster_t previous;
|
||||
cluster_t next;
|
||||
|
||||
if (difference == 0)
|
||||
exfat_bug("zero difference passed");
|
||||
if (node->start_cluster == EXFAT_CLUSTER_FREE)
|
||||
exfat_bug("unable to shrink empty file (%u clusters)", current);
|
||||
if (current < difference)
|
||||
exfat_bug("file underflow (%u < %u)", current, difference);
|
||||
|
||||
/* crop the file */
|
||||
if (current > difference)
|
||||
{
|
||||
cluster_t last = exfat_advance_cluster(ef, node,
|
||||
current - difference - 1);
|
||||
if (CLUSTER_INVALID(*ef->sb, last))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while shrinking", last);
|
||||
return -EIO;
|
||||
}
|
||||
previous = exfat_next_cluster(ef, node, last);
|
||||
if (!set_next_cluster(ef, node->is_contiguous, last,
|
||||
EXFAT_CLUSTER_END))
|
||||
return -EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
previous = node->start_cluster;
|
||||
node->start_cluster = EXFAT_CLUSTER_FREE;
|
||||
node->is_dirty = true;
|
||||
}
|
||||
node->fptr_index = 0;
|
||||
node->fptr_cluster = node->start_cluster;
|
||||
|
||||
/* free remaining clusters */
|
||||
while (difference--)
|
||||
{
|
||||
if (CLUSTER_INVALID(*ef->sb, previous))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while freeing after shrink",
|
||||
previous);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
next = exfat_next_cluster(ef, node, previous);
|
||||
if (!set_next_cluster(ef, node->is_contiguous, previous,
|
||||
EXFAT_CLUSTER_FREE))
|
||||
return -EIO;
|
||||
free_cluster(ef, previous);
|
||||
previous = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool erase_raw(struct exfat* ef, size_t size, off_t offset)
|
||||
{
|
||||
if (exfat_pwrite(ef->dev, ef->zero_cluster, size, offset) < 0)
|
||||
{
|
||||
exfat_error("failed to erase %zu bytes at %"PRId64, size, offset);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int erase_range(struct exfat* ef, struct exfat_node* node,
|
||||
uint64_t begin, uint64_t end)
|
||||
{
|
||||
uint64_t cluster_boundary;
|
||||
cluster_t cluster;
|
||||
|
||||
if (begin >= end)
|
||||
return 0;
|
||||
|
||||
cluster_boundary = (begin | (CLUSTER_SIZE(*ef->sb) - 1)) + 1;
|
||||
cluster = exfat_advance_cluster(ef, node,
|
||||
begin / CLUSTER_SIZE(*ef->sb));
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while erasing", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
/* erase from the beginning to the closest cluster boundary */
|
||||
if (!erase_raw(ef, MIN(cluster_boundary, end) - begin,
|
||||
exfat_c2o(ef, cluster) + begin % CLUSTER_SIZE(*ef->sb)))
|
||||
return -EIO;
|
||||
/* erase whole clusters */
|
||||
while (cluster_boundary < end)
|
||||
{
|
||||
cluster = exfat_next_cluster(ef, node, cluster);
|
||||
/* the cluster cannot be invalid because we have just allocated it */
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
exfat_bug("invalid cluster 0x%x after allocation", cluster);
|
||||
if (!erase_raw(ef, CLUSTER_SIZE(*ef->sb), exfat_c2o(ef, cluster)))
|
||||
return -EIO;
|
||||
cluster_boundary += CLUSTER_SIZE(*ef->sb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size,
|
||||
bool erase)
|
||||
{
|
||||
uint32_t c1 = bytes2clusters(ef, node->size);
|
||||
uint32_t c2 = bytes2clusters(ef, size);
|
||||
int rc = 0;
|
||||
|
||||
if (node->references == 0 && node->parent)
|
||||
exfat_bug("no references, node changes can be lost");
|
||||
|
||||
if (node->size == size)
|
||||
return 0;
|
||||
|
||||
if (c1 < c2)
|
||||
rc = grow_file(ef, node, c1, c2 - c1);
|
||||
else if (c1 > c2)
|
||||
rc = shrink_file(ef, node, c1, c1 - c2);
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (erase)
|
||||
{
|
||||
rc = erase_range(ef, node, node->size, size);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
exfat_update_mtime(node);
|
||||
node->size = size;
|
||||
node->is_dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t exfat_count_free_clusters(const struct exfat* ef)
|
||||
{
|
||||
uint32_t free_clusters = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ef->cmap.size; i++)
|
||||
if (BMAP_GET(ef->cmap.chunk, i) == 0)
|
||||
free_clusters++;
|
||||
return free_clusters;
|
||||
}
|
||||
|
||||
static int find_used_clusters(const struct exfat* ef,
|
||||
cluster_t* a, cluster_t* b)
|
||||
{
|
||||
const cluster_t end = le32_to_cpu(ef->sb->cluster_count);
|
||||
|
||||
/* find first used cluster */
|
||||
for (*a = *b + 1; *a < end; (*a)++)
|
||||
if (BMAP_GET(ef->cmap.chunk, *a - EXFAT_FIRST_DATA_CLUSTER))
|
||||
break;
|
||||
if (*a >= end)
|
||||
return 1;
|
||||
|
||||
/* find last contiguous used cluster */
|
||||
for (*b = *a; *b < end; (*b)++)
|
||||
if (BMAP_GET(ef->cmap.chunk, *b - EXFAT_FIRST_DATA_CLUSTER) == 0)
|
||||
{
|
||||
(*b)--;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b)
|
||||
{
|
||||
cluster_t ca, cb;
|
||||
|
||||
if (*a == 0 && *b == 0)
|
||||
ca = cb = EXFAT_FIRST_DATA_CLUSTER - 1;
|
||||
else
|
||||
{
|
||||
ca = s2c(ef, *a);
|
||||
cb = s2c(ef, *b);
|
||||
}
|
||||
if (find_used_clusters(ef, &ca, &cb) != 0)
|
||||
return 1;
|
||||
if (*a != 0 || *b != 0)
|
||||
*a = c2s(ef, ca);
|
||||
*b = c2s(ef, cb) + (CLUSTER_SIZE(*ef->sb) - 1) / SECTOR_SIZE(*ef->sb);
|
||||
return 0;
|
||||
}
|
66
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h
Normal file
66
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
compiler.h (09.06.13)
|
||||
Compiler-specific definitions. Note that unknown compiler is not a
|
||||
showstopper.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef COMPILER_H_INCLUDED
|
||||
#define COMPILER_H_INCLUDED
|
||||
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
#error C99-compliant compiler is required
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
#define PRINTF __attribute__((format(printf, 1, 2)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define PACKED __attribute__((packed))
|
||||
#if __has_extension(c_static_assert)
|
||||
#define USE_C11_STATIC_ASSERT
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define PRINTF __attribute__((format(printf, 1, 2)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define PACKED __attribute__((packed))
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#define USE_C11_STATIC_ASSERT
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define PRINTF
|
||||
#define NORETURN
|
||||
#define PACKED
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_C11_STATIC_ASSERT
|
||||
#define STATIC_ASSERT(cond) _Static_assert(cond, #cond)
|
||||
#else
|
||||
#define CONCAT2(a, b) a ## b
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define STATIC_ASSERT(cond) \
|
||||
extern void CONCAT1(static_assert, __LINE__)(int x[(cond) ? 1 : -1])
|
||||
#endif
|
||||
|
||||
#endif /* ifndef COMPILER_H_INCLUDED */
|
40
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h
Normal file
40
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* libexfat/config.h. Generated from config.h.in by configure. */
|
||||
/* libexfat/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "exfat"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "relan@users.noreply.github.com"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "Free exFAT implementation"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "Free exFAT implementation 1.3.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "exfat"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "https://github.com/relan/exfat"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.3.0"
|
||||
|
||||
/* Define if block devices are not supported. */
|
||||
/* #undef USE_UBLIO */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.3.0"
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
255
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h
Normal file
255
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
exfat.h (29.08.09)
|
||||
Definitions of structures and constants used in exFAT file system
|
||||
implementation.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef EXFAT_H_INCLUDED
|
||||
#define EXFAT_H_INCLUDED
|
||||
|
||||
#ifndef ANDROID
|
||||
/* Android.bp is used instead of autotools when targeting Android */
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "compiler.h"
|
||||
#include "exfatfs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define EXFAT_NAME_MAX 255
|
||||
/* UTF-16 encodes code points up to U+FFFF as single 16-bit code units.
|
||||
UTF-8 uses up to 3 bytes (i.e. 8-bit code units) to encode code points
|
||||
up to U+FFFF. One additional character is for null terminator. */
|
||||
#define EXFAT_UTF8_NAME_BUFFER_MAX (EXFAT_NAME_MAX * 3 + 1)
|
||||
#define EXFAT_UTF8_ENAME_BUFFER_MAX (EXFAT_ENAME_MAX * 3 + 1)
|
||||
|
||||
#define SECTOR_SIZE(sb) (1 << (sb).sector_bits)
|
||||
#define CLUSTER_SIZE(sb) (SECTOR_SIZE(sb) << (sb).spc_bits)
|
||||
#define CLUSTER_INVALID(sb, c) ((c) < EXFAT_FIRST_DATA_CLUSTER || \
|
||||
(c) - EXFAT_FIRST_DATA_CLUSTER >= le32_to_cpu((sb).cluster_count))
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define DIV_ROUND_UP(x, d) (((x) + (d) - 1) / (d))
|
||||
#define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d))
|
||||
|
||||
#define BMAP_SIZE(count) (ROUND_UP(count, sizeof(bitmap_t) * 8) / 8)
|
||||
#define BMAP_BLOCK(index) ((index) / sizeof(bitmap_t) / 8)
|
||||
#define BMAP_MASK(index) ((bitmap_t) 1 << ((index) % (sizeof(bitmap_t) * 8)))
|
||||
#define BMAP_GET(bitmap, index) \
|
||||
((bitmap)[BMAP_BLOCK(index)] & BMAP_MASK(index))
|
||||
#define BMAP_SET(bitmap, index) \
|
||||
((bitmap)[BMAP_BLOCK(index)] |= BMAP_MASK(index))
|
||||
#define BMAP_CLR(bitmap, index) \
|
||||
((bitmap)[BMAP_BLOCK(index)] &= ~BMAP_MASK(index))
|
||||
|
||||
#define EXFAT_REPAIR(hook, ef, ...) \
|
||||
(exfat_ask_to_fix(ef) && exfat_fix_ ## hook(ef, __VA_ARGS__))
|
||||
|
||||
/* The size of off_t type must be 64 bits. File systems larger than 2 GB will
|
||||
be corrupted with 32-bit off_t. */
|
||||
STATIC_ASSERT(sizeof(off_t) == 8);
|
||||
|
||||
struct exfat_node
|
||||
{
|
||||
struct exfat_node* parent;
|
||||
struct exfat_node* child;
|
||||
struct exfat_node* next;
|
||||
struct exfat_node* prev;
|
||||
|
||||
int references;
|
||||
uint32_t fptr_index;
|
||||
cluster_t fptr_cluster;
|
||||
off_t entry_offset;
|
||||
cluster_t start_cluster;
|
||||
uint16_t attrib;
|
||||
uint8_t continuations;
|
||||
bool is_contiguous : 1;
|
||||
bool is_cached : 1;
|
||||
bool is_dirty : 1;
|
||||
bool is_unlinked : 1;
|
||||
uint64_t size;
|
||||
time_t mtime, atime;
|
||||
le16_t name[EXFAT_NAME_MAX + 1];
|
||||
};
|
||||
|
||||
enum exfat_mode
|
||||
{
|
||||
EXFAT_MODE_RO,
|
||||
EXFAT_MODE_RW,
|
||||
EXFAT_MODE_ANY,
|
||||
};
|
||||
|
||||
struct exfat_dev;
|
||||
|
||||
struct exfat
|
||||
{
|
||||
struct exfat_dev* dev;
|
||||
struct exfat_super_block* sb;
|
||||
uint16_t* upcase;
|
||||
struct exfat_node* root;
|
||||
struct
|
||||
{
|
||||
cluster_t start_cluster;
|
||||
uint32_t size; /* in bits */
|
||||
bitmap_t* chunk;
|
||||
uint32_t chunk_size; /* in bits */
|
||||
bool dirty;
|
||||
}
|
||||
cmap;
|
||||
char label[EXFAT_UTF8_ENAME_BUFFER_MAX];
|
||||
void* zero_cluster;
|
||||
int dmask, fmask;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int ro;
|
||||
bool noatime;
|
||||
enum { EXFAT_REPAIR_NO, EXFAT_REPAIR_ASK, EXFAT_REPAIR_YES } repair;
|
||||
};
|
||||
|
||||
/* in-core nodes iterator */
|
||||
struct exfat_iterator
|
||||
{
|
||||
struct exfat_node* parent;
|
||||
struct exfat_node* current;
|
||||
};
|
||||
|
||||
struct exfat_human_bytes
|
||||
{
|
||||
uint64_t value;
|
||||
const char* unit;
|
||||
};
|
||||
|
||||
extern int exfat_errors;
|
||||
extern int exfat_errors_fixed;
|
||||
|
||||
#define VLOG_LOG 1
|
||||
#define VLOG_DEBUG 2
|
||||
void ventoy_syslog_newline(int level, const char *Fmt, ...);
|
||||
#define exfat_bug(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args)
|
||||
#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args)
|
||||
#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args)
|
||||
#define exfat_warn(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args)
|
||||
#define exfat_debug(fmt, args...) ventoy_syslog_newline(VLOG_DEBUG, fmt, ##args)
|
||||
|
||||
#if 0
|
||||
void exfat_bug(const char* format, ...) PRINTF NORETURN;
|
||||
void exfat_error(const char* format, ...) PRINTF;
|
||||
void exfat_warn(const char* format, ...) PRINTF;
|
||||
void exfat_debug(const char* format, ...) PRINTF;
|
||||
#endif /* #if 0 */
|
||||
|
||||
struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode);
|
||||
int exfat_close(struct exfat_dev* dev);
|
||||
int exfat_fsync(struct exfat_dev* dev);
|
||||
enum exfat_mode exfat_get_mode(const struct exfat_dev* dev);
|
||||
off_t exfat_get_size(const struct exfat_dev* dev);
|
||||
off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence);
|
||||
ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size);
|
||||
ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size);
|
||||
ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size,
|
||||
off_t offset);
|
||||
ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size,
|
||||
off_t offset);
|
||||
ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
|
||||
void* buffer, size_t size, off_t offset);
|
||||
ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
|
||||
const void* buffer, size_t size, off_t offset);
|
||||
|
||||
int exfat_opendir(struct exfat* ef, struct exfat_node* dir,
|
||||
struct exfat_iterator* it);
|
||||
void exfat_closedir(struct exfat* ef, struct exfat_iterator* it);
|
||||
struct exfat_node* exfat_readdir(struct exfat_iterator* it);
|
||||
int exfat_lookup(struct exfat* ef, struct exfat_node** node,
|
||||
const char* path);
|
||||
int exfat_split(struct exfat* ef, struct exfat_node** parent,
|
||||
struct exfat_node** node, le16_t* name, const char* path);
|
||||
|
||||
off_t exfat_c2o(const struct exfat* ef, cluster_t cluster);
|
||||
cluster_t exfat_next_cluster(const struct exfat* ef,
|
||||
const struct exfat_node* node, cluster_t cluster);
|
||||
cluster_t exfat_advance_cluster(const struct exfat* ef,
|
||||
struct exfat_node* node, uint32_t count);
|
||||
int exfat_flush_nodes(struct exfat* ef);
|
||||
int exfat_flush(struct exfat* ef);
|
||||
int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size,
|
||||
bool erase);
|
||||
uint32_t exfat_count_free_clusters(const struct exfat* ef);
|
||||
int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b);
|
||||
|
||||
void exfat_stat(const struct exfat* ef, const struct exfat_node* node,
|
||||
struct stat* stbuf);
|
||||
void exfat_get_name(const struct exfat_node* node,
|
||||
char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]);
|
||||
uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry);
|
||||
uint16_t exfat_add_checksum(const void* entry, uint16_t sum);
|
||||
le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n);
|
||||
uint32_t exfat_vbr_start_checksum(const void* sector, size_t size);
|
||||
uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum);
|
||||
le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name,
|
||||
size_t length);
|
||||
void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb);
|
||||
void exfat_print_info(const struct exfat_super_block* sb,
|
||||
uint32_t free_clusters);
|
||||
|
||||
int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
|
||||
size_t insize);
|
||||
int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
|
||||
size_t insize);
|
||||
size_t utf16_length(const le16_t* str);
|
||||
|
||||
struct exfat_node* exfat_get_node(struct exfat_node* node);
|
||||
void exfat_put_node(struct exfat* ef, struct exfat_node* node);
|
||||
int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node);
|
||||
int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir);
|
||||
void exfat_reset_cache(struct exfat* ef);
|
||||
int exfat_flush_node(struct exfat* ef, struct exfat_node* node);
|
||||
int exfat_unlink(struct exfat* ef, struct exfat_node* node);
|
||||
int exfat_rmdir(struct exfat* ef, struct exfat_node* node);
|
||||
int exfat_mknod(struct exfat* ef, const char* path);
|
||||
int exfat_mkdir(struct exfat* ef, const char* path);
|
||||
int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path);
|
||||
void exfat_utimes(struct exfat_node* node, const struct timespec tv[2]);
|
||||
void exfat_update_atime(struct exfat_node* node);
|
||||
void exfat_update_mtime(struct exfat_node* node);
|
||||
const char* exfat_get_label(struct exfat* ef);
|
||||
int exfat_set_label(struct exfat* ef, const char* label);
|
||||
|
||||
int exfat_mount(struct exfat* ef, const char* spec, const char* options);
|
||||
void exfat_unmount(struct exfat* ef);
|
||||
|
||||
time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec);
|
||||
void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
|
||||
uint8_t* centisec);
|
||||
void exfat_tzset(void);
|
||||
|
||||
bool exfat_ask_to_fix(const struct exfat* ef);
|
||||
bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
|
||||
uint32_t vbr_checksum);
|
||||
bool exfat_fix_invalid_node_checksum(const struct exfat* ef,
|
||||
struct exfat_node* node);
|
||||
bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir,
|
||||
const struct exfat_entry* entry, off_t offset);
|
||||
|
||||
#endif /* ifndef EXFAT_H_INCLUDED */
|
180
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h
Normal file
180
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
exfatfs.h (29.08.09)
|
||||
Definitions of structures and constants used in exFAT file system.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef EXFATFS_H_INCLUDED
|
||||
#define EXFATFS_H_INCLUDED
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "compiler.h"
|
||||
|
||||
typedef uint32_t cluster_t; /* cluster number */
|
||||
|
||||
#define EXFAT_FIRST_DATA_CLUSTER 2
|
||||
#define EXFAT_LAST_DATA_CLUSTER 0xfffffff6
|
||||
|
||||
#define EXFAT_CLUSTER_FREE 0 /* free cluster */
|
||||
#define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad sector */
|
||||
#define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */
|
||||
|
||||
#define EXFAT_STATE_MOUNTED 2
|
||||
|
||||
struct exfat_super_block
|
||||
{
|
||||
uint8_t jump[3]; /* 0x00 jmp and nop instructions */
|
||||
uint8_t oem_name[8]; /* 0x03 "EXFAT " */
|
||||
uint8_t __unused1[53]; /* 0x0B always 0 */
|
||||
le64_t sector_start; /* 0x40 partition first sector */
|
||||
le64_t sector_count; /* 0x48 partition sectors count */
|
||||
le32_t fat_sector_start; /* 0x50 FAT first sector */
|
||||
le32_t fat_sector_count; /* 0x54 FAT sectors count */
|
||||
le32_t cluster_sector_start; /* 0x58 first cluster sector */
|
||||
le32_t cluster_count; /* 0x5C total clusters count */
|
||||
le32_t rootdir_cluster; /* 0x60 first cluster of the root dir */
|
||||
le32_t volume_serial; /* 0x64 volume serial number */
|
||||
struct /* 0x68 FS version */
|
||||
{
|
||||
uint8_t minor;
|
||||
uint8_t major;
|
||||
}
|
||||
version;
|
||||
le16_t volume_state; /* 0x6A volume state flags */
|
||||
uint8_t sector_bits; /* 0x6C sector size as (1 << n) */
|
||||
uint8_t spc_bits; /* 0x6D sectors per cluster as (1 << n) */
|
||||
uint8_t fat_count; /* 0x6E always 1 */
|
||||
uint8_t drive_no; /* 0x6F always 0x80 */
|
||||
uint8_t allocated_percent; /* 0x70 percentage of allocated space */
|
||||
uint8_t __unused2[397]; /* 0x71 always 0 */
|
||||
le16_t boot_signature; /* the value of 0xAA55 */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_super_block) == 512);
|
||||
|
||||
#define EXFAT_ENTRY_VALID 0x80
|
||||
#define EXFAT_ENTRY_CONTINUED 0x40
|
||||
#define EXFAT_ENTRY_OPTIONAL 0x20
|
||||
|
||||
#define EXFAT_ENTRY_BITMAP (0x01 | EXFAT_ENTRY_VALID)
|
||||
#define EXFAT_ENTRY_UPCASE (0x02 | EXFAT_ENTRY_VALID)
|
||||
#define EXFAT_ENTRY_LABEL (0x03 | EXFAT_ENTRY_VALID)
|
||||
#define EXFAT_ENTRY_FILE (0x05 | EXFAT_ENTRY_VALID)
|
||||
#define EXFAT_ENTRY_FILE_INFO (0x00 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)
|
||||
#define EXFAT_ENTRY_FILE_NAME (0x01 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)
|
||||
#define EXFAT_ENTRY_FILE_TAIL (0x00 | EXFAT_ENTRY_VALID \
|
||||
| EXFAT_ENTRY_CONTINUED \
|
||||
| EXFAT_ENTRY_OPTIONAL)
|
||||
|
||||
struct exfat_entry /* common container for all entries */
|
||||
{
|
||||
uint8_t type; /* any of EXFAT_ENTRY_xxx */
|
||||
uint8_t data[31];
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry) == 32);
|
||||
|
||||
#define EXFAT_ENAME_MAX 15
|
||||
|
||||
struct exfat_entry_bitmap /* allocated clusters bitmap */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_BITMAP */
|
||||
uint8_t __unknown1[19];
|
||||
le32_t start_cluster;
|
||||
le64_t size; /* in bytes */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_bitmap) == 32);
|
||||
|
||||
#define EXFAT_UPCASE_CHARS 0x10000
|
||||
|
||||
struct exfat_entry_upcase /* upper case translation table */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_UPCASE */
|
||||
uint8_t __unknown1[3];
|
||||
le32_t checksum;
|
||||
uint8_t __unknown2[12];
|
||||
le32_t start_cluster;
|
||||
le64_t size; /* in bytes */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_upcase) == 32);
|
||||
|
||||
struct exfat_entry_label /* volume label */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_LABEL */
|
||||
uint8_t length; /* number of characters */
|
||||
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_label) == 32);
|
||||
|
||||
#define EXFAT_ATTRIB_RO 0x01
|
||||
#define EXFAT_ATTRIB_HIDDEN 0x02
|
||||
#define EXFAT_ATTRIB_SYSTEM 0x04
|
||||
#define EXFAT_ATTRIB_VOLUME 0x08
|
||||
#define EXFAT_ATTRIB_DIR 0x10
|
||||
#define EXFAT_ATTRIB_ARCH 0x20
|
||||
|
||||
struct exfat_entry_meta1 /* file or directory info (part 1) */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_FILE */
|
||||
uint8_t continuations;
|
||||
le16_t checksum;
|
||||
le16_t attrib; /* combination of EXFAT_ATTRIB_xxx */
|
||||
le16_t __unknown1;
|
||||
le16_t crtime, crdate; /* creation date and time */
|
||||
le16_t mtime, mdate; /* latest modification date and time */
|
||||
le16_t atime, adate; /* latest access date and time */
|
||||
uint8_t crtime_cs; /* creation time in cs (centiseconds) */
|
||||
uint8_t mtime_cs; /* latest modification time in cs */
|
||||
uint8_t __unknown2[10];
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_meta1) == 32);
|
||||
|
||||
#define EXFAT_FLAG_ALWAYS1 (1u << 0)
|
||||
#define EXFAT_FLAG_CONTIGUOUS (1u << 1)
|
||||
|
||||
struct exfat_entry_meta2 /* file or directory info (part 2) */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_FILE_INFO */
|
||||
uint8_t flags; /* combination of EXFAT_FLAG_xxx */
|
||||
uint8_t __unknown1;
|
||||
uint8_t name_length;
|
||||
le16_t name_hash;
|
||||
le16_t __unknown2;
|
||||
le64_t valid_size; /* in bytes, less or equal to size */
|
||||
uint8_t __unknown3[4];
|
||||
le32_t start_cluster;
|
||||
le64_t size; /* in bytes */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_meta2) == 32);
|
||||
|
||||
struct exfat_entry_name /* file or directory name */
|
||||
{
|
||||
uint8_t type; /* EXFAT_ENTRY_FILE_NAME */
|
||||
uint8_t __unknown;
|
||||
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
|
||||
}
|
||||
PACKED;
|
||||
STATIC_ASSERT(sizeof(struct exfat_entry_name) == 32);
|
||||
|
||||
#endif /* ifndef EXFATFS_H_INCLUDED */
|
511
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c
Normal file
511
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c
Normal file
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
io.c (02.09.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#if defined(__APPLE__)
|
||||
#include <sys/disk.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#elif __linux__
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#ifdef USE_UBLIO
|
||||
#include <sys/uio.h>
|
||||
#include <ublio.h>
|
||||
#endif
|
||||
|
||||
struct exfat_dev
|
||||
{
|
||||
int fd;
|
||||
enum exfat_mode mode;
|
||||
off_t size; /* in bytes */
|
||||
#ifdef USE_UBLIO
|
||||
off_t pos;
|
||||
ublio_filehandle_t ufh;
|
||||
#endif
|
||||
};
|
||||
|
||||
int g_vtoy_exfat_disk_fd = -1;
|
||||
uint64_t g_vtoy_exfat_part_size = 0;
|
||||
|
||||
static bool is_open(int fd)
|
||||
{
|
||||
return fcntl(fd, F_GETFD) != -1;
|
||||
}
|
||||
|
||||
static int open_ro(const char* spec)
|
||||
{
|
||||
return open(spec, O_RDONLY);
|
||||
}
|
||||
|
||||
static int open_rw(const char* spec)
|
||||
{
|
||||
int fd = open(spec, O_RDWR);
|
||||
#ifdef __linux__
|
||||
int ro = 0;
|
||||
|
||||
/*
|
||||
This ioctl is needed because after "blockdev --setro" kernel still
|
||||
allows to open the device in read-write mode but fails writes.
|
||||
*/
|
||||
if (fd != -1 && ioctl(fd, BLKROGET, &ro) == 0 && ro)
|
||||
{
|
||||
close(fd);
|
||||
errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode)
|
||||
{
|
||||
struct exfat_dev* dev;
|
||||
struct stat stbuf;
|
||||
#ifdef USE_UBLIO
|
||||
struct ublio_param up;
|
||||
#endif
|
||||
|
||||
/* The system allocates file descriptors sequentially. If we have been
|
||||
started with stdin (0), stdout (1) or stderr (2) closed, the system
|
||||
will give us descriptor 0, 1 or 2 later when we open block device,
|
||||
FUSE communication pipe, etc. As a result, functions using stdin,
|
||||
stdout or stderr will actually work with a different thing and can
|
||||
corrupt it. Protect descriptors 0, 1 and 2 from such misuse. */
|
||||
while (!is_open(STDIN_FILENO)
|
||||
|| !is_open(STDOUT_FILENO)
|
||||
|| !is_open(STDERR_FILENO))
|
||||
{
|
||||
/* we don't need those descriptors, let them leak */
|
||||
if (open("/dev/null", O_RDWR) == -1)
|
||||
{
|
||||
exfat_error("failed to open /dev/null");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dev = malloc(sizeof(struct exfat_dev));
|
||||
if (dev == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate memory for device structure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case EXFAT_MODE_RO:
|
||||
dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd;
|
||||
if (dev->fd == -1)
|
||||
{
|
||||
free(dev);
|
||||
exfat_error("failed to open '%s' in read-only mode: %s", spec,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
dev->mode = EXFAT_MODE_RO;
|
||||
break;
|
||||
case EXFAT_MODE_RW:
|
||||
dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd;
|
||||
if (dev->fd == -1)
|
||||
{
|
||||
free(dev);
|
||||
exfat_error("failed to open '%s' in read-write mode: %s", spec,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
dev->mode = EXFAT_MODE_RW;
|
||||
break;
|
||||
case EXFAT_MODE_ANY:
|
||||
dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd;
|
||||
if (dev->fd != -1)
|
||||
{
|
||||
dev->mode = EXFAT_MODE_RW;
|
||||
break;
|
||||
}
|
||||
dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd;
|
||||
if (dev->fd != -1)
|
||||
{
|
||||
dev->mode = EXFAT_MODE_RO;
|
||||
exfat_warn("'%s' is write-protected, mounting read-only", spec);
|
||||
break;
|
||||
}
|
||||
free(dev);
|
||||
exfat_error("failed to open '%s': %s", spec, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(dev->fd, &stbuf) != 0)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to fstat '%s'", spec);
|
||||
return NULL;
|
||||
}
|
||||
if (!S_ISBLK(stbuf.st_mode) &&
|
||||
!S_ISCHR(stbuf.st_mode) &&
|
||||
!S_ISREG(stbuf.st_mode))
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("'%s' is neither a device, nor a regular file", spec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (!S_ISREG(stbuf.st_mode))
|
||||
{
|
||||
uint32_t block_size = 0;
|
||||
uint64_t blocks = 0;
|
||||
|
||||
if (ioctl(dev->fd, DKIOCGETBLOCKSIZE, &block_size) != 0)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to get block size");
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(dev->fd, DKIOCGETBLOCKCOUNT, &blocks) != 0)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to get blocks count");
|
||||
return NULL;
|
||||
}
|
||||
dev->size = blocks * block_size;
|
||||
}
|
||||
else
|
||||
#elif defined(__OpenBSD__)
|
||||
if (!S_ISREG(stbuf.st_mode))
|
||||
{
|
||||
struct disklabel lab;
|
||||
struct partition* pp;
|
||||
char* partition;
|
||||
|
||||
if (ioctl(dev->fd, DIOCGDINFO, &lab) == -1)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to get disklabel");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Don't need to check that partition letter is valid as we won't get
|
||||
this far otherwise. */
|
||||
partition = strchr(spec, '\0') - 1;
|
||||
pp = &(lab.d_partitions[*partition - 'a']);
|
||||
dev->size = DL_GETPSIZE(pp) * lab.d_secsize;
|
||||
|
||||
if (pp->p_fstype != FS_NTFS)
|
||||
exfat_warn("partition type is not 0x07 (NTFS/exFAT); "
|
||||
"you can fix this with fdisk(8)");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* works for Linux, FreeBSD, Solaris */
|
||||
dev->size = exfat_seek(dev, 0, SEEK_END);
|
||||
if (dev->size <= 0)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to get size of '%s'", spec);
|
||||
return NULL;
|
||||
}
|
||||
if (exfat_seek(dev, 0, SEEK_SET) == -1)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to seek to the beginning of '%s'", spec);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_UBLIO
|
||||
memset(&up, 0, sizeof(struct ublio_param));
|
||||
up.up_blocksize = 256 * 1024;
|
||||
up.up_items = 64;
|
||||
up.up_grace = 32;
|
||||
up.up_priv = &dev->fd;
|
||||
|
||||
dev->pos = 0;
|
||||
dev->ufh = ublio_open(&up);
|
||||
if (dev->ufh == NULL)
|
||||
{
|
||||
close(dev->fd);
|
||||
free(dev);
|
||||
exfat_error("failed to initialize ublio");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
int exfat_close(struct exfat_dev* dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
#ifdef USE_UBLIO
|
||||
if (ublio_close(dev->ufh) != 0)
|
||||
{
|
||||
exfat_error("failed to close ublio");
|
||||
rc = -EIO;
|
||||
}
|
||||
#endif
|
||||
if (dev->fd != g_vtoy_exfat_disk_fd)
|
||||
{
|
||||
if (close(dev->fd) != 0)
|
||||
{
|
||||
exfat_error("failed to close device: %s", strerror(errno));
|
||||
rc = -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
free(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int exfat_fsync(struct exfat_dev* dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
#ifdef USE_UBLIO
|
||||
if (ublio_fsync(dev->ufh) != 0)
|
||||
{
|
||||
exfat_error("ublio fsync failed");
|
||||
rc = -EIO;
|
||||
}
|
||||
#endif
|
||||
if (fsync(dev->fd) != 0)
|
||||
{
|
||||
exfat_error("fsync failed: %s", strerror(errno));
|
||||
rc = -EIO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
enum exfat_mode exfat_get_mode(const struct exfat_dev* dev)
|
||||
{
|
||||
return dev->mode;
|
||||
}
|
||||
|
||||
|
||||
off_t exfat_get_size(const struct exfat_dev* dev)
|
||||
{
|
||||
return dev->size;
|
||||
}
|
||||
|
||||
off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence)
|
||||
{
|
||||
#ifdef USE_UBLIO
|
||||
/* XXX SEEK_CUR will be handled incorrectly */
|
||||
return dev->pos = lseek(dev->fd, offset, whence);
|
||||
#else
|
||||
|
||||
if (SEEK_SET == whence)
|
||||
{
|
||||
if (offset > g_vtoy_exfat_part_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lseek(dev->fd, 512 * 2048 + offset, SEEK_SET);
|
||||
return offset;
|
||||
}
|
||||
else if (SEEK_END == whence)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
offset = 512 * 2048 + g_vtoy_exfat_part_size;
|
||||
lseek(dev->fd, offset, SEEK_SET);
|
||||
return (off_t)g_vtoy_exfat_part_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
exfat_error("Invalid SEEK_END offset %llu", (unsigned long long)offset);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exfat_error("Invalid seek whence %d", whence);
|
||||
return lseek(dev->fd, offset, whence);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size)
|
||||
{
|
||||
#ifdef USE_UBLIO
|
||||
ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos);
|
||||
if (result >= 0)
|
||||
dev->pos += size;
|
||||
return result;
|
||||
#else
|
||||
return read(dev->fd, buffer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size)
|
||||
{
|
||||
#ifdef USE_UBLIO
|
||||
ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos);
|
||||
if (result >= 0)
|
||||
dev->pos += size;
|
||||
return result;
|
||||
#else
|
||||
return write(dev->fd, buffer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size,
|
||||
off_t offset)
|
||||
{
|
||||
#ifdef USE_UBLIO
|
||||
return ublio_pread(dev->ufh, buffer, size, offset);
|
||||
#else
|
||||
return pread(dev->fd, buffer, size, offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size,
|
||||
off_t offset)
|
||||
{
|
||||
#ifdef USE_UBLIO
|
||||
return ublio_pwrite(dev->ufh, buffer, size, offset);
|
||||
#else
|
||||
return pwrite(dev->fd, buffer, size, offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
|
||||
void* buffer, size_t size, off_t offset)
|
||||
{
|
||||
cluster_t cluster;
|
||||
char* bufp = buffer;
|
||||
off_t lsize, loffset, remainder;
|
||||
|
||||
if (offset >= node->size)
|
||||
return 0;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while reading", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
loffset = offset % CLUSTER_SIZE(*ef->sb);
|
||||
remainder = MIN(size, node->size - offset);
|
||||
while (remainder > 0)
|
||||
{
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while reading", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder);
|
||||
if (exfat_pread(ef->dev, bufp, lsize,
|
||||
exfat_c2o(ef, cluster) + loffset) < 0)
|
||||
{
|
||||
exfat_error("failed to read cluster %#x", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
bufp += lsize;
|
||||
loffset = 0;
|
||||
remainder -= lsize;
|
||||
cluster = exfat_next_cluster(ef, node, cluster);
|
||||
}
|
||||
if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime)
|
||||
exfat_update_atime(node);
|
||||
return MIN(size, node->size - offset) - remainder;
|
||||
}
|
||||
|
||||
ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
|
||||
const void* buffer, size_t size, off_t offset)
|
||||
{
|
||||
int rc;
|
||||
cluster_t cluster;
|
||||
const char* bufp = buffer;
|
||||
off_t lsize, loffset, remainder;
|
||||
|
||||
if (offset > node->size)
|
||||
{
|
||||
rc = exfat_truncate(ef, node, offset, true);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
if (offset + size > node->size)
|
||||
{
|
||||
rc = exfat_truncate(ef, node, offset + size, false);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while writing", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
loffset = offset % CLUSTER_SIZE(*ef->sb);
|
||||
remainder = size;
|
||||
while (remainder > 0)
|
||||
{
|
||||
if (CLUSTER_INVALID(*ef->sb, cluster))
|
||||
{
|
||||
exfat_error("invalid cluster 0x%x while writing", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder);
|
||||
if (exfat_pwrite(ef->dev, bufp, lsize,
|
||||
exfat_c2o(ef, cluster) + loffset) < 0)
|
||||
{
|
||||
exfat_error("failed to write cluster %#x", cluster);
|
||||
return -EIO;
|
||||
}
|
||||
bufp += lsize;
|
||||
loffset = 0;
|
||||
remainder -= lsize;
|
||||
cluster = exfat_next_cluster(ef, node, cluster);
|
||||
}
|
||||
if (!(node->attrib & EXFAT_ATTRIB_DIR))
|
||||
/* directory's mtime should be updated by the caller only when it
|
||||
creates or removes something in this directory */
|
||||
exfat_update_mtime(node);
|
||||
return size - remainder;
|
||||
}
|
224
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c
Normal file
224
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
lookup.c (02.09.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int exfat_opendir(struct exfat* ef, struct exfat_node* dir,
|
||||
struct exfat_iterator* it)
|
||||
{
|
||||
int rc;
|
||||
|
||||
exfat_get_node(dir);
|
||||
it->parent = dir;
|
||||
it->current = NULL;
|
||||
rc = exfat_cache_directory(ef, dir);
|
||||
if (rc != 0)
|
||||
exfat_put_node(ef, dir);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void exfat_closedir(struct exfat* ef, struct exfat_iterator* it)
|
||||
{
|
||||
exfat_put_node(ef, it->parent);
|
||||
it->parent = NULL;
|
||||
it->current = NULL;
|
||||
}
|
||||
|
||||
struct exfat_node* exfat_readdir(struct exfat_iterator* it)
|
||||
{
|
||||
if (it->current == NULL)
|
||||
it->current = it->parent->child;
|
||||
else
|
||||
it->current = it->current->next;
|
||||
|
||||
if (it->current != NULL)
|
||||
return exfat_get_node(it->current);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int compare_char(struct exfat* ef, uint16_t a, uint16_t b)
|
||||
{
|
||||
return (int) ef->upcase[a] - (int) ef->upcase[b];
|
||||
}
|
||||
|
||||
static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b)
|
||||
{
|
||||
while (le16_to_cpu(*a) && le16_to_cpu(*b))
|
||||
{
|
||||
int rc = compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
|
||||
}
|
||||
|
||||
static int lookup_name(struct exfat* ef, struct exfat_node* parent,
|
||||
struct exfat_node** node, const char* name, size_t n)
|
||||
{
|
||||
struct exfat_iterator it;
|
||||
le16_t buffer[EXFAT_NAME_MAX + 1];
|
||||
int rc;
|
||||
|
||||
*node = NULL;
|
||||
|
||||
rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
rc = exfat_opendir(ef, parent, &it);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
while ((*node = exfat_readdir(&it)))
|
||||
{
|
||||
if (compare_name(ef, buffer, (*node)->name) == 0)
|
||||
{
|
||||
exfat_closedir(ef, &it);
|
||||
return 0;
|
||||
}
|
||||
exfat_put_node(ef, *node);
|
||||
}
|
||||
exfat_closedir(ef, &it);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static size_t get_comp(const char* path, const char** comp)
|
||||
{
|
||||
const char* end;
|
||||
|
||||
*comp = path + strspn(path, "/"); /* skip leading slashes */
|
||||
end = strchr(*comp, '/');
|
||||
if (end == NULL)
|
||||
return strlen(*comp);
|
||||
else
|
||||
return end - *comp;
|
||||
}
|
||||
|
||||
int exfat_lookup(struct exfat* ef, struct exfat_node** node,
|
||||
const char* path)
|
||||
{
|
||||
struct exfat_node* parent;
|
||||
const char* p;
|
||||
size_t n;
|
||||
int rc;
|
||||
|
||||
/* start from the root directory */
|
||||
parent = *node = exfat_get_node(ef->root);
|
||||
for (p = path; (n = get_comp(p, &p)); p += n)
|
||||
{
|
||||
if (n == 1 && *p == '.') /* skip "." component */
|
||||
continue;
|
||||
rc = lookup_name(ef, parent, node, p, n);
|
||||
if (rc != 0)
|
||||
{
|
||||
exfat_put_node(ef, parent);
|
||||
return rc;
|
||||
}
|
||||
exfat_put_node(ef, parent);
|
||||
parent = *node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_last_comp(const char* comp, size_t length)
|
||||
{
|
||||
const char* p = comp + length;
|
||||
|
||||
return get_comp(p, &p) == 0;
|
||||
}
|
||||
|
||||
static bool is_allowed(const char* comp, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
switch (comp[i])
|
||||
{
|
||||
case 0x01 ... 0x1f:
|
||||
case '/':
|
||||
case '\\':
|
||||
case ':':
|
||||
case '*':
|
||||
case '?':
|
||||
case '"':
|
||||
case '<':
|
||||
case '>':
|
||||
case '|':
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int exfat_split(struct exfat* ef, struct exfat_node** parent,
|
||||
struct exfat_node** node, le16_t* name, const char* path)
|
||||
{
|
||||
const char* p;
|
||||
size_t n;
|
||||
int rc;
|
||||
|
||||
memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
|
||||
*parent = *node = exfat_get_node(ef->root);
|
||||
for (p = path; (n = get_comp(p, &p)); p += n)
|
||||
{
|
||||
if (n == 1 && *p == '.')
|
||||
continue;
|
||||
if (is_last_comp(p, n))
|
||||
{
|
||||
if (!is_allowed(p, n))
|
||||
{
|
||||
/* contains characters that are not allowed */
|
||||
exfat_put_node(ef, *parent);
|
||||
return -ENOENT;
|
||||
}
|
||||
rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n);
|
||||
if (rc != 0)
|
||||
{
|
||||
exfat_put_node(ef, *parent);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = lookup_name(ef, *parent, node, p, n);
|
||||
if (rc != 0 && rc != -ENOENT)
|
||||
{
|
||||
exfat_put_node(ef, *parent);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
rc = lookup_name(ef, *parent, node, p, n);
|
||||
if (rc != 0)
|
||||
{
|
||||
exfat_put_node(ef, *parent);
|
||||
return rc;
|
||||
}
|
||||
exfat_put_node(ef, *parent);
|
||||
*parent = *node;
|
||||
}
|
||||
exfat_bug("impossible");
|
||||
|
||||
return 1;
|
||||
}
|
389
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c
Normal file
389
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
mount.c (22.10.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static uint64_t rootdir_size(const struct exfat* ef)
|
||||
{
|
||||
uint32_t clusters = 0;
|
||||
uint32_t clusters_max = le32_to_cpu(ef->sb->cluster_count);
|
||||
cluster_t rootdir_cluster = le32_to_cpu(ef->sb->rootdir_cluster);
|
||||
|
||||
/* Iterate all clusters of the root directory to calculate its size.
|
||||
It can't be contiguous because there is no flag to indicate this. */
|
||||
do
|
||||
{
|
||||
if (clusters == clusters_max) /* infinite loop detected */
|
||||
{
|
||||
exfat_error("root directory cannot occupy all %d clusters",
|
||||
clusters);
|
||||
return 0;
|
||||
}
|
||||
if (CLUSTER_INVALID(*ef->sb, rootdir_cluster))
|
||||
{
|
||||
exfat_error("bad cluster %#x while reading root directory",
|
||||
rootdir_cluster);
|
||||
return 0;
|
||||
}
|
||||
rootdir_cluster = exfat_next_cluster(ef, ef->root, rootdir_cluster);
|
||||
clusters++;
|
||||
}
|
||||
while (rootdir_cluster != EXFAT_CLUSTER_END);
|
||||
|
||||
return (uint64_t) clusters * CLUSTER_SIZE(*ef->sb);
|
||||
}
|
||||
|
||||
static const char* get_option(const char* options, const char* option_name)
|
||||
{
|
||||
const char* p;
|
||||
size_t length = strlen(option_name);
|
||||
|
||||
for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name))
|
||||
if ((p == options || p[-1] == ',') && p[length] == '=')
|
||||
return p + length + 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int get_int_option(const char* options, const char* option_name,
|
||||
int base, int default_value)
|
||||
{
|
||||
const char* p = get_option(options, option_name);
|
||||
|
||||
if (p == NULL)
|
||||
return default_value;
|
||||
return strtol(p, NULL, base);
|
||||
}
|
||||
|
||||
static bool match_option(const char* options, const char* option_name)
|
||||
{
|
||||
const char* p;
|
||||
size_t length = strlen(option_name);
|
||||
|
||||
for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name))
|
||||
if ((p == options || p[-1] == ',') &&
|
||||
(p[length] == ',' || p[length] == '\0'))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void parse_options(struct exfat* ef, const char* options)
|
||||
{
|
||||
int opt_umask;
|
||||
|
||||
opt_umask = get_int_option(options, "umask", 8, 0);
|
||||
ef->dmask = get_int_option(options, "dmask", 8, opt_umask);
|
||||
ef->fmask = get_int_option(options, "fmask", 8, opt_umask);
|
||||
|
||||
ef->uid = get_int_option(options, "uid", 10, geteuid());
|
||||
ef->gid = get_int_option(options, "gid", 10, getegid());
|
||||
|
||||
ef->noatime = match_option(options, "noatime");
|
||||
|
||||
switch (get_int_option(options, "repair", 10, 0))
|
||||
{
|
||||
case 1:
|
||||
ef->repair = EXFAT_REPAIR_ASK;
|
||||
break;
|
||||
case 2:
|
||||
ef->repair = EXFAT_REPAIR_YES;
|
||||
break;
|
||||
default:
|
||||
ef->repair = EXFAT_REPAIR_NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool verify_vbr_checksum(const struct exfat* ef, void* sector)
|
||||
{
|
||||
off_t sector_size = SECTOR_SIZE(*ef->sb);
|
||||
uint32_t vbr_checksum;
|
||||
int i;
|
||||
|
||||
if (exfat_pread(ef->dev, sector, sector_size, 0) < 0)
|
||||
{
|
||||
exfat_error("failed to read boot sector");
|
||||
return false;
|
||||
}
|
||||
vbr_checksum = exfat_vbr_start_checksum(sector, sector_size);
|
||||
for (i = 1; i < 11; i++)
|
||||
{
|
||||
if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0)
|
||||
{
|
||||
exfat_error("failed to read VBR sector");
|
||||
return false;
|
||||
}
|
||||
vbr_checksum = exfat_vbr_add_checksum(sector, sector_size,
|
||||
vbr_checksum);
|
||||
}
|
||||
if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0)
|
||||
{
|
||||
exfat_error("failed to read VBR checksum sector");
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < sector_size / sizeof(vbr_checksum); i++)
|
||||
if (le32_to_cpu(((const le32_t*) sector)[i]) != vbr_checksum)
|
||||
{
|
||||
exfat_error("invalid VBR checksum 0x%x (expected 0x%x)",
|
||||
le32_to_cpu(((const le32_t*) sector)[i]), vbr_checksum);
|
||||
if (!EXFAT_REPAIR(invalid_vbr_checksum, ef, sector, vbr_checksum))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int commit_super_block(const struct exfat* ef)
|
||||
{
|
||||
if (exfat_pwrite(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0)
|
||||
{
|
||||
exfat_error("failed to write super block");
|
||||
return 1;
|
||||
}
|
||||
return exfat_fsync(ef->dev);
|
||||
}
|
||||
|
||||
static int prepare_super_block(const struct exfat* ef)
|
||||
{
|
||||
if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED)
|
||||
exfat_warn("volume was not unmounted cleanly");
|
||||
|
||||
if (ef->ro)
|
||||
return 0;
|
||||
|
||||
ef->sb->volume_state = cpu_to_le16(
|
||||
le16_to_cpu(ef->sb->volume_state) | EXFAT_STATE_MOUNTED);
|
||||
return commit_super_block(ef);
|
||||
}
|
||||
|
||||
static void exfat_free(struct exfat* ef)
|
||||
{
|
||||
exfat_close(ef->dev); /* first of all, close the descriptor */
|
||||
ef->dev = NULL; /* struct exfat_dev is freed by exfat_close() */
|
||||
free(ef->root);
|
||||
ef->root = NULL;
|
||||
free(ef->zero_cluster);
|
||||
ef->zero_cluster = NULL;
|
||||
free(ef->cmap.chunk);
|
||||
ef->cmap.chunk = NULL;
|
||||
free(ef->upcase);
|
||||
ef->upcase = NULL;
|
||||
free(ef->sb);
|
||||
ef->sb = NULL;
|
||||
}
|
||||
|
||||
int exfat_mount(struct exfat* ef, const char* spec, const char* options)
|
||||
{
|
||||
int rc;
|
||||
enum exfat_mode mode;
|
||||
|
||||
exfat_tzset();
|
||||
memset(ef, 0, sizeof(struct exfat));
|
||||
|
||||
parse_options(ef, options);
|
||||
|
||||
if (match_option(options, "ro"))
|
||||
mode = EXFAT_MODE_RO;
|
||||
else if (match_option(options, "ro_fallback"))
|
||||
mode = EXFAT_MODE_ANY;
|
||||
else
|
||||
mode = EXFAT_MODE_RW;
|
||||
ef->dev = exfat_open(spec, mode);
|
||||
if (ef->dev == NULL)
|
||||
return -EIO;
|
||||
if (exfat_get_mode(ef->dev) == EXFAT_MODE_RO)
|
||||
{
|
||||
if (mode == EXFAT_MODE_ANY)
|
||||
ef->ro = -1;
|
||||
else
|
||||
ef->ro = 1;
|
||||
}
|
||||
|
||||
ef->sb = malloc(sizeof(struct exfat_super_block));
|
||||
if (ef->sb == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate memory for the super block");
|
||||
exfat_free(ef);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(ef->sb, 0, sizeof(struct exfat_super_block));
|
||||
|
||||
if (exfat_pread(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0)
|
||||
{
|
||||
exfat_error("failed to read boot sector");
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
if (memcmp(ef->sb->oem_name, "EXFAT ", 8) != 0)
|
||||
{
|
||||
exfat_error("exFAT file system is not found");
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
/* sector cannot be smaller than 512 bytes */
|
||||
if (ef->sb->sector_bits < 9)
|
||||
{
|
||||
exfat_error("too small sector size: 2^%hhd", ef->sb->sector_bits);
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
/* officially exFAT supports cluster size up to 32 MB */
|
||||
if ((int) ef->sb->sector_bits + (int) ef->sb->spc_bits > 25)
|
||||
{
|
||||
exfat_error("too big cluster size: 2^(%hhd+%hhd)",
|
||||
ef->sb->sector_bits, ef->sb->spc_bits);
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
ef->zero_cluster = malloc(CLUSTER_SIZE(*ef->sb));
|
||||
if (ef->zero_cluster == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate zero sector");
|
||||
exfat_free(ef);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* use zero_cluster as a temporary buffer for VBR checksum verification */
|
||||
if (!verify_vbr_checksum(ef, ef->zero_cluster))
|
||||
{
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
memset(ef->zero_cluster, 0, CLUSTER_SIZE(*ef->sb));
|
||||
if (ef->sb->version.major != 1 || ef->sb->version.minor != 0)
|
||||
{
|
||||
exfat_error("unsupported exFAT version: %hhu.%hhu",
|
||||
ef->sb->version.major, ef->sb->version.minor);
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
if (ef->sb->fat_count != 1)
|
||||
{
|
||||
exfat_error("unsupported FAT count: %hhu", ef->sb->fat_count);
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
if (le64_to_cpu(ef->sb->sector_count) * SECTOR_SIZE(*ef->sb) >
|
||||
exfat_get_size(ef->dev))
|
||||
{
|
||||
/* this can cause I/O errors later but we don't fail mounting to let
|
||||
user rescue data */
|
||||
exfat_warn("file system in sectors is larger than device: "
|
||||
"%"PRIu64" * %d > %"PRIu64,
|
||||
le64_to_cpu(ef->sb->sector_count), SECTOR_SIZE(*ef->sb),
|
||||
exfat_get_size(ef->dev));
|
||||
}
|
||||
if ((off_t) le32_to_cpu(ef->sb->cluster_count) * CLUSTER_SIZE(*ef->sb) >
|
||||
exfat_get_size(ef->dev))
|
||||
{
|
||||
exfat_error("file system in clusters is larger than device: "
|
||||
"%u * %d > %"PRIu64,
|
||||
le32_to_cpu(ef->sb->cluster_count), CLUSTER_SIZE(*ef->sb),
|
||||
exfat_get_size(ef->dev));
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ef->root = malloc(sizeof(struct exfat_node));
|
||||
if (ef->root == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate root node");
|
||||
exfat_free(ef);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(ef->root, 0, sizeof(struct exfat_node));
|
||||
ef->root->attrib = EXFAT_ATTRIB_DIR;
|
||||
ef->root->start_cluster = le32_to_cpu(ef->sb->rootdir_cluster);
|
||||
ef->root->fptr_cluster = ef->root->start_cluster;
|
||||
ef->root->name[0] = cpu_to_le16('\0');
|
||||
ef->root->size = rootdir_size(ef);
|
||||
if (ef->root->size == 0)
|
||||
{
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
/* exFAT does not have time attributes for the root directory */
|
||||
ef->root->mtime = 0;
|
||||
ef->root->atime = 0;
|
||||
/* always keep at least 1 reference to the root node */
|
||||
exfat_get_node(ef->root);
|
||||
|
||||
rc = exfat_cache_directory(ef, ef->root);
|
||||
if (rc != 0)
|
||||
goto error;
|
||||
if (ef->upcase == NULL)
|
||||
{
|
||||
exfat_error("upcase table is not found");
|
||||
goto error;
|
||||
}
|
||||
if (ef->cmap.chunk == NULL)
|
||||
{
|
||||
exfat_error("clusters bitmap is not found");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (prepare_super_block(ef) != 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
exfat_put_node(ef, ef->root);
|
||||
exfat_reset_cache(ef);
|
||||
exfat_free(ef);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void finalize_super_block(struct exfat* ef)
|
||||
{
|
||||
if (ef->ro)
|
||||
return;
|
||||
|
||||
ef->sb->volume_state = cpu_to_le16(
|
||||
le16_to_cpu(ef->sb->volume_state) & ~EXFAT_STATE_MOUNTED);
|
||||
|
||||
/* Some implementations set the percentage of allocated space to 0xff
|
||||
on FS creation and never update it. In this case leave it as is. */
|
||||
if (ef->sb->allocated_percent != 0xff)
|
||||
{
|
||||
uint32_t free, total;
|
||||
|
||||
free = exfat_count_free_clusters(ef);
|
||||
total = le32_to_cpu(ef->sb->cluster_count);
|
||||
ef->sb->allocated_percent = ((total - free) * 100 + total / 2) / total;
|
||||
}
|
||||
|
||||
commit_super_block(ef); /* ignore return code */
|
||||
}
|
||||
|
||||
void exfat_unmount(struct exfat* ef)
|
||||
{
|
||||
exfat_flush_nodes(ef); /* ignore return code */
|
||||
exfat_flush(ef); /* ignore return code */
|
||||
exfat_put_node(ef, ef->root);
|
||||
exfat_reset_cache(ef);
|
||||
finalize_super_block(ef);
|
||||
exfat_free(ef); /* will close the descriptor */
|
||||
}
|
1226
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c
Normal file
1226
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c
Normal file
File diff suppressed because it is too large
Load diff
63
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h
Normal file
63
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
platform.h (14.05.13)
|
||||
OS-specific code (libc-specific in fact). Note that systems with the
|
||||
same kernel can use different libc implementations.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_H_INCLUDED
|
||||
#define PLATFORM_H_INCLUDED
|
||||
|
||||
#if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__)
|
||||
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#define exfat_bswap16(x) bswap_16(x)
|
||||
#define exfat_bswap32(x) bswap_32(x)
|
||||
#define exfat_bswap64(x) bswap_64(x)
|
||||
#define EXFAT_BYTE_ORDER __BYTE_ORDER
|
||||
#define EXFAT_LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
#define EXFAT_BIG_ENDIAN __BIG_ENDIAN
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <machine/endian.h>
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define exfat_bswap16(x) OSSwapInt16(x)
|
||||
#define exfat_bswap32(x) OSSwapInt32(x)
|
||||
#define exfat_bswap64(x) OSSwapInt64(x)
|
||||
#define EXFAT_BYTE_ORDER BYTE_ORDER
|
||||
#define EXFAT_LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#define EXFAT_BIG_ENDIAN BIG_ENDIAN
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
||||
#include <sys/endian.h>
|
||||
#define exfat_bswap16(x) bswap16(x)
|
||||
#define exfat_bswap32(x) bswap32(x)
|
||||
#define exfat_bswap64(x) bswap64(x)
|
||||
#define EXFAT_BYTE_ORDER _BYTE_ORDER
|
||||
#define EXFAT_LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define EXFAT_BIG_ENDIAN _BIG_ENDIAN
|
||||
|
||||
#else
|
||||
#error Unknown platform
|
||||
#endif
|
||||
|
||||
#endif /* ifndef PLATFORM_H_INCLUDED */
|
103
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c
Normal file
103
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
repair.c (09.03.17)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <strings.h>
|
||||
|
||||
int exfat_errors_fixed;
|
||||
|
||||
bool exfat_ask_to_fix(const struct exfat* ef)
|
||||
{
|
||||
const char* question = "Fix (Y/N)?";
|
||||
char answer[8];
|
||||
bool yeah, nope;
|
||||
|
||||
switch (ef->repair)
|
||||
{
|
||||
case EXFAT_REPAIR_NO:
|
||||
return false;
|
||||
case EXFAT_REPAIR_YES:
|
||||
printf("%s %s", question, "Y\n");
|
||||
return true;
|
||||
case EXFAT_REPAIR_ASK:
|
||||
do
|
||||
{
|
||||
printf("%s ", question);
|
||||
fflush(stdout);
|
||||
if (fgets(answer, sizeof(answer), stdin))
|
||||
{
|
||||
yeah = strcasecmp(answer, "Y\n") == 0;
|
||||
nope = strcasecmp(answer, "N\n") == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yeah = false;
|
||||
nope = true;
|
||||
}
|
||||
}
|
||||
while (!yeah && !nope);
|
||||
return yeah;
|
||||
}
|
||||
exfat_bug("invalid repair option value: %d", ef->repair);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
|
||||
uint32_t vbr_checksum)
|
||||
{
|
||||
size_t i;
|
||||
off_t sector_size = SECTOR_SIZE(*ef->sb);
|
||||
|
||||
for (i = 0; i < sector_size / sizeof(vbr_checksum); i++)
|
||||
((le32_t*) sector)[i] = cpu_to_le32(vbr_checksum);
|
||||
if (exfat_pwrite(ef->dev, sector, sector_size, 11 * sector_size) < 0)
|
||||
{
|
||||
exfat_error("failed to write correct VBR checksum");
|
||||
return false;
|
||||
}
|
||||
exfat_errors_fixed++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exfat_fix_invalid_node_checksum(const struct exfat* ef,
|
||||
struct exfat_node* node)
|
||||
{
|
||||
/* checksum will be rewritten by exfat_flush_node() */
|
||||
node->is_dirty = true;
|
||||
|
||||
exfat_errors_fixed++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir,
|
||||
const struct exfat_entry* entry, off_t offset)
|
||||
{
|
||||
struct exfat_entry deleted = *entry;
|
||||
|
||||
deleted.type &= ~EXFAT_ENTRY_VALID;
|
||||
if (exfat_generic_pwrite(ef, dir, &deleted, sizeof(struct exfat_entry),
|
||||
offset) != sizeof(struct exfat_entry))
|
||||
return false;
|
||||
|
||||
exfat_errors_fixed++;
|
||||
return true;
|
||||
}
|
164
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c
Normal file
164
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
time.c (03.02.12)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
|
||||
/* timezone offset from UTC in seconds; positive for western timezones,
|
||||
negative for eastern ones */
|
||||
static long exfat_timezone;
|
||||
|
||||
#define SEC_IN_MIN 60ll
|
||||
#define SEC_IN_HOUR (60 * SEC_IN_MIN)
|
||||
#define SEC_IN_DAY (24 * SEC_IN_HOUR)
|
||||
#define SEC_IN_YEAR (365 * SEC_IN_DAY) /* not leap year */
|
||||
/* Unix epoch started at 0:00:00 UTC 1 January 1970 */
|
||||
#define UNIX_EPOCH_YEAR 1970
|
||||
/* exFAT epoch started at 0:00:00 UTC 1 January 1980 */
|
||||
#define EXFAT_EPOCH_YEAR 1980
|
||||
/* number of years from Unix epoch to exFAT epoch */
|
||||
#define EPOCH_DIFF_YEAR (EXFAT_EPOCH_YEAR - UNIX_EPOCH_YEAR)
|
||||
/* number of days from Unix epoch to exFAT epoch (considering leap days) */
|
||||
#define EPOCH_DIFF_DAYS (EPOCH_DIFF_YEAR * 365 + EPOCH_DIFF_YEAR / 4)
|
||||
/* number of seconds from Unix epoch to exFAT epoch (considering leap days) */
|
||||
#define EPOCH_DIFF_SEC (EPOCH_DIFF_DAYS * SEC_IN_DAY)
|
||||
/* number of leap years passed from exFAT epoch to the specified year
|
||||
(excluding the specified year itself) */
|
||||
#define LEAP_YEARS(year) ((EXFAT_EPOCH_YEAR + (year) - 1) / 4 \
|
||||
- (EXFAT_EPOCH_YEAR - 1) / 4)
|
||||
/* checks whether the specified year is leap */
|
||||
#define IS_LEAP_YEAR(year) ((EXFAT_EPOCH_YEAR + (year)) % 4 == 0)
|
||||
|
||||
static const time_t days_in_year[] =
|
||||
{
|
||||
/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
|
||||
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
||||
};
|
||||
|
||||
time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec)
|
||||
{
|
||||
time_t unix_time = EPOCH_DIFF_SEC;
|
||||
uint16_t ndate = le16_to_cpu(date);
|
||||
uint16_t ntime = le16_to_cpu(time);
|
||||
|
||||
uint16_t day = ndate & 0x1f; /* 5 bits, 1-31 */
|
||||
uint16_t month = ndate >> 5 & 0xf; /* 4 bits, 1-12 */
|
||||
uint16_t year = ndate >> 9; /* 7 bits, 1-127 (+1980) */
|
||||
|
||||
uint16_t twosec = ntime & 0x1f; /* 5 bits, 0-29 (2 sec granularity) */
|
||||
uint16_t min = ntime >> 5 & 0x3f; /* 6 bits, 0-59 */
|
||||
uint16_t hour = ntime >> 11; /* 5 bits, 0-23 */
|
||||
|
||||
if (day == 0 || month == 0 || month > 12)
|
||||
{
|
||||
exfat_error("bad date %u-%02hu-%02hu",
|
||||
year + EXFAT_EPOCH_YEAR, month, day);
|
||||
return 0;
|
||||
}
|
||||
if (hour > 23 || min > 59 || twosec > 29)
|
||||
{
|
||||
exfat_error("bad time %hu:%02hu:%02u",
|
||||
hour, min, twosec * 2);
|
||||
return 0;
|
||||
}
|
||||
if (centisec > 199)
|
||||
{
|
||||
exfat_error("bad centiseconds count %hhu", centisec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* every 4th year between 1904 and 2096 is leap */
|
||||
unix_time += year * SEC_IN_YEAR + LEAP_YEARS(year) * SEC_IN_DAY;
|
||||
unix_time += days_in_year[month] * SEC_IN_DAY;
|
||||
/* if it's leap year and February has passed we should add 1 day */
|
||||
if ((EXFAT_EPOCH_YEAR + year) % 4 == 0 && month > 2)
|
||||
unix_time += SEC_IN_DAY;
|
||||
unix_time += (day - 1) * SEC_IN_DAY;
|
||||
|
||||
unix_time += hour * SEC_IN_HOUR;
|
||||
unix_time += min * SEC_IN_MIN;
|
||||
/* exFAT represents time with 2 sec granularity */
|
||||
unix_time += twosec * 2;
|
||||
unix_time += centisec / 100;
|
||||
|
||||
/* exFAT stores timestamps in local time, so we correct it to UTC */
|
||||
unix_time += exfat_timezone;
|
||||
|
||||
return unix_time;
|
||||
}
|
||||
|
||||
void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
|
||||
uint8_t* centisec)
|
||||
{
|
||||
time_t shift = EPOCH_DIFF_SEC + exfat_timezone;
|
||||
uint16_t day, month, year;
|
||||
uint16_t twosec, min, hour;
|
||||
int days;
|
||||
int i;
|
||||
|
||||
/* time before exFAT epoch cannot be represented */
|
||||
if (unix_time < shift)
|
||||
unix_time = shift;
|
||||
|
||||
unix_time -= shift;
|
||||
|
||||
days = unix_time / SEC_IN_DAY;
|
||||
year = (4 * days) / (4 * 365 + 1);
|
||||
days -= year * 365 + LEAP_YEARS(year);
|
||||
month = 0;
|
||||
for (i = 1; i <= 12; i++)
|
||||
{
|
||||
int leap_day = (IS_LEAP_YEAR(year) && i == 2);
|
||||
int leap_sub = (IS_LEAP_YEAR(year) && i >= 3);
|
||||
|
||||
if (i == 12 || days - leap_sub < days_in_year[i + 1] + leap_day)
|
||||
{
|
||||
month = i;
|
||||
days -= days_in_year[i] + leap_sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
day = days + 1;
|
||||
|
||||
hour = (unix_time % SEC_IN_DAY) / SEC_IN_HOUR;
|
||||
min = (unix_time % SEC_IN_HOUR) / SEC_IN_MIN;
|
||||
twosec = (unix_time % SEC_IN_MIN) / 2;
|
||||
|
||||
*date = cpu_to_le16(day | (month << 5) | (year << 9));
|
||||
*time = cpu_to_le16(twosec | (min << 5) | (hour << 11));
|
||||
if (centisec)
|
||||
*centisec = (unix_time % 2) * 100;
|
||||
}
|
||||
|
||||
void exfat_tzset(void)
|
||||
{
|
||||
time_t now;
|
||||
struct tm* utc;
|
||||
|
||||
tzset();
|
||||
now = time(NULL);
|
||||
utc = gmtime(&now);
|
||||
/* gmtime() always sets tm_isdst to 0 because daylight savings never
|
||||
affect UTC. Setting tm_isdst to -1 makes mktime() to determine whether
|
||||
summer time is in effect. */
|
||||
utc->tm_isdst = -1;
|
||||
exfat_timezone = mktime(utc) - now;
|
||||
}
|
245
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c
Normal file
245
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c
Normal file
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
utf.c (13.09.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <errno.h>
|
||||
|
||||
static char* wchar_to_utf8(char* output, wchar_t wc, size_t outsize)
|
||||
{
|
||||
if (wc <= 0x7f)
|
||||
{
|
||||
if (outsize < 1)
|
||||
return NULL;
|
||||
*output++ = (char) wc;
|
||||
}
|
||||
else if (wc <= 0x7ff)
|
||||
{
|
||||
if (outsize < 2)
|
||||
return NULL;
|
||||
*output++ = 0xc0 | (wc >> 6);
|
||||
*output++ = 0x80 | (wc & 0x3f);
|
||||
}
|
||||
else if (wc <= 0xffff)
|
||||
{
|
||||
if (outsize < 3)
|
||||
return NULL;
|
||||
*output++ = 0xe0 | (wc >> 12);
|
||||
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
||||
*output++ = 0x80 | (wc & 0x3f);
|
||||
}
|
||||
else if (wc <= 0x1fffff)
|
||||
{
|
||||
if (outsize < 4)
|
||||
return NULL;
|
||||
*output++ = 0xf0 | (wc >> 18);
|
||||
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
||||
*output++ = 0x80 | (wc & 0x3f);
|
||||
}
|
||||
else if (wc <= 0x3ffffff)
|
||||
{
|
||||
if (outsize < 5)
|
||||
return NULL;
|
||||
*output++ = 0xf8 | (wc >> 24);
|
||||
*output++ = 0x80 | ((wc >> 18) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
||||
*output++ = 0x80 | (wc & 0x3f);
|
||||
}
|
||||
else if (wc <= 0x7fffffff)
|
||||
{
|
||||
if (outsize < 6)
|
||||
return NULL;
|
||||
*output++ = 0xfc | (wc >> 30);
|
||||
*output++ = 0x80 | ((wc >> 24) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 18) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
||||
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
||||
*output++ = 0x80 | (wc & 0x3f);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc,
|
||||
size_t insize)
|
||||
{
|
||||
if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800)
|
||||
{
|
||||
if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00)
|
||||
return NULL;
|
||||
*wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
|
||||
*wc |= (le16_to_cpu(input[1]) & 0x3ff);
|
||||
*wc += 0x10000;
|
||||
return input + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*wc = le16_to_cpu(*input);
|
||||
return input + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
|
||||
size_t insize)
|
||||
{
|
||||
const le16_t* inp = input;
|
||||
char* outp = output;
|
||||
wchar_t wc;
|
||||
|
||||
while (inp - input < insize)
|
||||
{
|
||||
inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
|
||||
if (inp == NULL)
|
||||
{
|
||||
exfat_error("illegal UTF-16 sequence");
|
||||
return -EILSEQ;
|
||||
}
|
||||
outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
|
||||
if (outp == NULL)
|
||||
{
|
||||
exfat_error("name is too long");
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
if (wc == 0)
|
||||
return 0;
|
||||
}
|
||||
if (outp - output >= outsize)
|
||||
{
|
||||
exfat_error("name is too long");
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
*outp = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* utf8_to_wchar(const char* input, wchar_t* wc,
|
||||
size_t insize)
|
||||
{
|
||||
if ((input[0] & 0x80) == 0 && insize >= 1)
|
||||
{
|
||||
*wc = (wchar_t) input[0];
|
||||
return input + 1;
|
||||
}
|
||||
if ((input[0] & 0xe0) == 0xc0 && insize >= 2)
|
||||
{
|
||||
*wc = (((wchar_t) input[0] & 0x1f) << 6) |
|
||||
((wchar_t) input[1] & 0x3f);
|
||||
return input + 2;
|
||||
}
|
||||
if ((input[0] & 0xf0) == 0xe0 && insize >= 3)
|
||||
{
|
||||
*wc = (((wchar_t) input[0] & 0x0f) << 12) |
|
||||
(((wchar_t) input[1] & 0x3f) << 6) |
|
||||
((wchar_t) input[2] & 0x3f);
|
||||
return input + 3;
|
||||
}
|
||||
if ((input[0] & 0xf8) == 0xf0 && insize >= 4)
|
||||
{
|
||||
*wc = (((wchar_t) input[0] & 0x07) << 18) |
|
||||
(((wchar_t) input[1] & 0x3f) << 12) |
|
||||
(((wchar_t) input[2] & 0x3f) << 6) |
|
||||
((wchar_t) input[3] & 0x3f);
|
||||
return input + 4;
|
||||
}
|
||||
if ((input[0] & 0xfc) == 0xf8 && insize >= 5)
|
||||
{
|
||||
*wc = (((wchar_t) input[0] & 0x03) << 24) |
|
||||
(((wchar_t) input[1] & 0x3f) << 18) |
|
||||
(((wchar_t) input[2] & 0x3f) << 12) |
|
||||
(((wchar_t) input[3] & 0x3f) << 6) |
|
||||
((wchar_t) input[4] & 0x3f);
|
||||
return input + 5;
|
||||
}
|
||||
if ((input[0] & 0xfe) == 0xfc && insize >= 6)
|
||||
{
|
||||
*wc = (((wchar_t) input[0] & 0x01) << 30) |
|
||||
(((wchar_t) input[1] & 0x3f) << 24) |
|
||||
(((wchar_t) input[2] & 0x3f) << 18) |
|
||||
(((wchar_t) input[3] & 0x3f) << 12) |
|
||||
(((wchar_t) input[4] & 0x3f) << 6) |
|
||||
((wchar_t) input[5] & 0x3f);
|
||||
return input + 6;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize)
|
||||
{
|
||||
if (wc <= 0xffff) /* if character is from BMP */
|
||||
{
|
||||
if (outsize == 0)
|
||||
return NULL;
|
||||
output[0] = cpu_to_le16(wc);
|
||||
return output + 1;
|
||||
}
|
||||
if (outsize < 2)
|
||||
return NULL;
|
||||
wc -= 0x10000;
|
||||
output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
|
||||
output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
|
||||
return output + 2;
|
||||
}
|
||||
|
||||
int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
|
||||
size_t insize)
|
||||
{
|
||||
const char* inp = input;
|
||||
le16_t* outp = output;
|
||||
wchar_t wc;
|
||||
|
||||
while (inp - input < insize)
|
||||
{
|
||||
inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
|
||||
if (inp == NULL)
|
||||
{
|
||||
exfat_error("illegal UTF-8 sequence");
|
||||
return -EILSEQ;
|
||||
}
|
||||
outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
|
||||
if (outp == NULL)
|
||||
{
|
||||
exfat_error("name is too long");
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
if (wc == 0)
|
||||
break;
|
||||
}
|
||||
if (outp - output >= outsize)
|
||||
{
|
||||
exfat_error("name is too long");
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
*outp = cpu_to_le16(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t utf16_length(const le16_t* str)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while (le16_to_cpu(str[i]))
|
||||
i++;
|
||||
return i;
|
||||
}
|
180
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c
Normal file
180
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
utils.c (04.09.09)
|
||||
exFAT file system implementation library.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2010-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "exfat.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
void exfat_stat(const struct exfat* ef, const struct exfat_node* node,
|
||||
struct stat* stbuf)
|
||||
{
|
||||
memset(stbuf, 0, sizeof(struct stat));
|
||||
if (node->attrib & EXFAT_ATTRIB_DIR)
|
||||
stbuf->st_mode = S_IFDIR | (0777 & ~ef->dmask);
|
||||
else
|
||||
stbuf->st_mode = S_IFREG | (0777 & ~ef->fmask);
|
||||
stbuf->st_nlink = 1;
|
||||
stbuf->st_uid = ef->uid;
|
||||
stbuf->st_gid = ef->gid;
|
||||
stbuf->st_size = node->size;
|
||||
stbuf->st_blocks = ROUND_UP(node->size, CLUSTER_SIZE(*ef->sb)) / 512;
|
||||
stbuf->st_mtime = node->mtime;
|
||||
stbuf->st_atime = node->atime;
|
||||
/* set ctime to mtime to ensure we don't break programs that rely on ctime
|
||||
(e.g. rsync) */
|
||||
stbuf->st_ctime = node->mtime;
|
||||
}
|
||||
|
||||
void exfat_get_name(const struct exfat_node* node,
|
||||
char buffer[EXFAT_UTF8_NAME_BUFFER_MAX])
|
||||
{
|
||||
if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX,
|
||||
EXFAT_NAME_MAX) != 0)
|
||||
exfat_bug("failed to convert name to UTF-8");
|
||||
}
|
||||
|
||||
static uint16_t add_checksum_byte(uint16_t sum, uint8_t byte)
|
||||
{
|
||||
return ((sum << 15) | (sum >> 1)) + byte;
|
||||
}
|
||||
|
||||
static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
sum = add_checksum_byte(sum, ((const uint8_t*) buffer)[i]);
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry)
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(struct exfat_entry); i++)
|
||||
if (i != 2 && i != 3) /* skip checksum field itself */
|
||||
sum = add_checksum_byte(sum, ((const uint8_t*) entry)[i]);
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint16_t exfat_add_checksum(const void* entry, uint16_t sum)
|
||||
{
|
||||
return add_checksum_bytes(sum, entry, sizeof(struct exfat_entry));
|
||||
}
|
||||
|
||||
le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n)
|
||||
{
|
||||
uint16_t checksum;
|
||||
int i;
|
||||
|
||||
checksum = exfat_start_checksum((const struct exfat_entry_meta1*) entries);
|
||||
for (i = 1; i < n; i++)
|
||||
checksum = exfat_add_checksum(entries + i, checksum);
|
||||
return cpu_to_le16(checksum);
|
||||
}
|
||||
|
||||
uint32_t exfat_vbr_start_checksum(const void* sector, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
/* skip volume_state and allocated_percent fields */
|
||||
if (i != 0x6a && i != 0x6b && i != 0x70)
|
||||
sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name,
|
||||
size_t length)
|
||||
{
|
||||
size_t i;
|
||||
uint16_t hash = 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
uint16_t c = le16_to_cpu(name[i]);
|
||||
|
||||
/* convert to upper case */
|
||||
c = ef->upcase[c];
|
||||
|
||||
hash = ((hash << 15) | (hash >> 1)) + (c & 0xff);
|
||||
hash = ((hash << 15) | (hash >> 1)) + (c >> 8);
|
||||
}
|
||||
return cpu_to_le16(hash);
|
||||
}
|
||||
|
||||
void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb)
|
||||
{
|
||||
size_t i;
|
||||
/* 16 EB (minus 1 byte) is the largest size that can be represented by
|
||||
uint64_t */
|
||||
const char* units[] = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB"};
|
||||
uint64_t divisor = 1;
|
||||
uint64_t temp = 0;
|
||||
|
||||
for (i = 0; ; i++, divisor *= 1024)
|
||||
{
|
||||
temp = (value + divisor / 2) / divisor;
|
||||
|
||||
if (temp == 0)
|
||||
break;
|
||||
if (temp / 1024 * 1024 == temp)
|
||||
continue;
|
||||
if (temp < 10240)
|
||||
break;
|
||||
}
|
||||
hb->value = temp;
|
||||
hb->unit = units[i];
|
||||
}
|
||||
|
||||
void exfat_print_info(const struct exfat_super_block* sb,
|
||||
uint32_t free_clusters)
|
||||
{
|
||||
struct exfat_human_bytes hb;
|
||||
off_t total_space = le64_to_cpu(sb->sector_count) * SECTOR_SIZE(*sb);
|
||||
off_t avail_space = (off_t) free_clusters * CLUSTER_SIZE(*sb);
|
||||
|
||||
printf("File system version %hhu.%hhu\n",
|
||||
sb->version.major, sb->version.minor);
|
||||
exfat_humanize_bytes(SECTOR_SIZE(*sb), &hb);
|
||||
printf("Sector size %10"PRIu64" %s\n", hb.value, hb.unit);
|
||||
exfat_humanize_bytes(CLUSTER_SIZE(*sb), &hb);
|
||||
printf("Cluster size %10"PRIu64" %s\n", hb.value, hb.unit);
|
||||
exfat_humanize_bytes(total_space, &hb);
|
||||
printf("Volume size %10"PRIu64" %s\n", hb.value, hb.unit);
|
||||
exfat_humanize_bytes(total_space - avail_space, &hb);
|
||||
printf("Used space %10"PRIu64" %s\n", hb.value, hb.unit);
|
||||
exfat_humanize_bytes(avail_space, &hb);
|
||||
printf("Available space %10"PRIu64" %s\n", hb.value, hb.unit);
|
||||
}
|
79
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c
Normal file
79
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
cbm.c (09.11.10)
|
||||
Clusters Bitmap creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cbm.h"
|
||||
#include "fat.h"
|
||||
#include "uct.h"
|
||||
#include "rootdir.h"
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
static off_t cbm_alignment(void)
|
||||
{
|
||||
return get_cluster_size();
|
||||
}
|
||||
|
||||
static off_t cbm_size(void)
|
||||
{
|
||||
return DIV_ROUND_UP(
|
||||
(get_volume_size() - get_position(&cbm)) / get_cluster_size(),
|
||||
CHAR_BIT);
|
||||
}
|
||||
|
||||
static int cbm_write(struct exfat_dev* dev)
|
||||
{
|
||||
uint32_t allocated_clusters =
|
||||
DIV_ROUND_UP(cbm.get_size(), get_cluster_size()) +
|
||||
DIV_ROUND_UP(uct.get_size(), get_cluster_size()) +
|
||||
DIV_ROUND_UP(rootdir.get_size(), get_cluster_size());
|
||||
size_t bitmap_size = ROUND_UP(allocated_clusters, CHAR_BIT);
|
||||
bitmap_t* bitmap = malloc(BMAP_SIZE(bitmap_size));
|
||||
size_t i;
|
||||
|
||||
if (bitmap == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate bitmap of %zu bytes",
|
||||
BMAP_SIZE(bitmap_size));
|
||||
return 1;
|
||||
}
|
||||
memset(bitmap, 0, BMAP_SIZE(bitmap_size));
|
||||
|
||||
for (i = 0; i < bitmap_size; i++)
|
||||
if (i < allocated_clusters)
|
||||
BMAP_SET(bitmap, i);
|
||||
if (exfat_write(dev, bitmap, bitmap_size / CHAR_BIT) < 0)
|
||||
{
|
||||
free(bitmap);
|
||||
exfat_error("failed to write bitmap of %zu bytes",
|
||||
bitmap_size / CHAR_BIT);
|
||||
return 1;
|
||||
}
|
||||
free(bitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fs_object cbm =
|
||||
{
|
||||
.get_alignment = cbm_alignment,
|
||||
.get_size = cbm_size,
|
||||
.write = cbm_write,
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
cbm.h (09.11.10)
|
||||
Clusters Bitmap creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_CBM_H_INCLUDED
|
||||
#define MKFS_CBM_H_INCLUDED
|
||||
|
||||
#include "mkexfat.h"
|
||||
|
||||
extern const struct fs_object cbm;
|
||||
|
||||
#endif /* ifndef MKFS_CBM_H_INCLUDED */
|
88
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c
Normal file
88
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
fat.c (09.11.10)
|
||||
File Allocation Table creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "fat.h"
|
||||
#include "cbm.h"
|
||||
#include "uct.h"
|
||||
#include "rootdir.h"
|
||||
#include <unistd.h>
|
||||
|
||||
static off_t fat_alignment(void)
|
||||
{
|
||||
return (off_t) 128 * get_sector_size();
|
||||
}
|
||||
|
||||
static off_t fat_size(void)
|
||||
{
|
||||
return get_volume_size() / get_cluster_size() * sizeof(cluster_t);
|
||||
}
|
||||
|
||||
static cluster_t fat_write_entry(struct exfat_dev* dev, cluster_t cluster,
|
||||
cluster_t value)
|
||||
{
|
||||
le32_t fat_entry = cpu_to_le32(value);
|
||||
if (exfat_write(dev, &fat_entry, sizeof(fat_entry)) < 0)
|
||||
{
|
||||
exfat_error("failed to write FAT entry 0x%x", value);
|
||||
return 0;
|
||||
}
|
||||
return cluster + 1;
|
||||
}
|
||||
|
||||
static cluster_t fat_write_entries(struct exfat_dev* dev, cluster_t cluster,
|
||||
uint64_t length)
|
||||
{
|
||||
cluster_t end = cluster + DIV_ROUND_UP(length, get_cluster_size());
|
||||
|
||||
while (cluster < end - 1)
|
||||
{
|
||||
cluster = fat_write_entry(dev, cluster, cluster + 1);
|
||||
if (cluster == 0)
|
||||
return 0;
|
||||
}
|
||||
return fat_write_entry(dev, cluster, EXFAT_CLUSTER_END);
|
||||
}
|
||||
|
||||
static int fat_write(struct exfat_dev* dev)
|
||||
{
|
||||
cluster_t c = 0;
|
||||
|
||||
if (!(c = fat_write_entry(dev, c, 0xfffffff8))) /* media type */
|
||||
return 1;
|
||||
if (!(c = fat_write_entry(dev, c, 0xffffffff))) /* some weird constant */
|
||||
return 1;
|
||||
if (!(c = fat_write_entries(dev, c, cbm.get_size())))
|
||||
return 1;
|
||||
if (!(c = fat_write_entries(dev, c, uct.get_size())))
|
||||
return 1;
|
||||
if (!(c = fat_write_entries(dev, c, rootdir.get_size())))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fs_object fat =
|
||||
{
|
||||
.get_alignment = fat_alignment,
|
||||
.get_size = fat_size,
|
||||
.write = fat_write,
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
fat.h (09.11.10)
|
||||
File Allocation Table creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_FAT_H_INCLUDED
|
||||
#define MKFS_FAT_H_INCLUDED
|
||||
|
||||
#include "mkexfat.h"
|
||||
|
||||
extern const struct fs_object fat;
|
||||
|
||||
#endif /* ifndef MKFS_FAT_H_INCLUDED */
|
167
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c
Normal file
167
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
mkexfat.c (22.04.12)
|
||||
FS creation engine.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "mkexfat.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int check_size(off_t volume_size)
|
||||
{
|
||||
const struct fs_object** pp;
|
||||
off_t position = 0;
|
||||
|
||||
for (pp = objects; *pp; pp++)
|
||||
{
|
||||
position = ROUND_UP(position, (*pp)->get_alignment());
|
||||
position += (*pp)->get_size();
|
||||
}
|
||||
|
||||
if (position > volume_size)
|
||||
{
|
||||
struct exfat_human_bytes vhb;
|
||||
|
||||
exfat_humanize_bytes(volume_size, &vhb);
|
||||
exfat_error("too small device (%"PRIu64" %s)", vhb.value, vhb.unit);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int erase_object(struct exfat_dev* dev, const void* block,
|
||||
size_t block_size, off_t start, off_t size)
|
||||
{
|
||||
const off_t block_count = DIV_ROUND_UP(size, block_size);
|
||||
off_t i;
|
||||
|
||||
if (exfat_seek(dev, start, SEEK_SET) == (off_t) -1)
|
||||
{
|
||||
exfat_error("seek to 0x%"PRIx64" failed", start);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < size; i += block_size)
|
||||
{
|
||||
if (exfat_write(dev, block, MIN(size - i, block_size)) < 0)
|
||||
{
|
||||
exfat_error("failed to erase block %"PRIu64"/%"PRIu64
|
||||
" at 0x%"PRIx64, i + 1, block_count, start);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int erase(struct exfat_dev* dev)
|
||||
{
|
||||
const struct fs_object** pp;
|
||||
off_t position = 0;
|
||||
const size_t block_size = 1024 * 1024;
|
||||
void* block = malloc(block_size);
|
||||
|
||||
if (block == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate erase block of %zu bytes", block_size);
|
||||
return 1;
|
||||
}
|
||||
memset(block, 0, block_size);
|
||||
|
||||
for (pp = objects; *pp; pp++)
|
||||
{
|
||||
position = ROUND_UP(position, (*pp)->get_alignment());
|
||||
if (erase_object(dev, block, block_size, position,
|
||||
(*pp)->get_size()) != 0)
|
||||
{
|
||||
free(block);
|
||||
return 1;
|
||||
}
|
||||
position += (*pp)->get_size();
|
||||
}
|
||||
|
||||
free(block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create(struct exfat_dev* dev)
|
||||
{
|
||||
const struct fs_object** pp;
|
||||
off_t position = 0;
|
||||
|
||||
for (pp = objects; *pp; pp++)
|
||||
{
|
||||
position = ROUND_UP(position, (*pp)->get_alignment());
|
||||
if (exfat_seek(dev, position, SEEK_SET) == (off_t) -1)
|
||||
{
|
||||
exfat_error("seek to 0x%"PRIx64" failed", position);
|
||||
return 1;
|
||||
}
|
||||
if ((*pp)->write(dev) != 0)
|
||||
return 1;
|
||||
position += (*pp)->get_size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mkfs(struct exfat_dev* dev, off_t volume_size)
|
||||
{
|
||||
if (check_size(volume_size) != 0)
|
||||
return 1;
|
||||
|
||||
exfat_debug("Creating... ");
|
||||
//fputs("Creating... ", stdout);
|
||||
//fflush(stdout);
|
||||
if (erase(dev) != 0)
|
||||
return 1;
|
||||
if (create(dev) != 0)
|
||||
return 1;
|
||||
//puts("done.");
|
||||
|
||||
//fputs("Flushing... ", stdout);
|
||||
//fflush(stdout);
|
||||
exfat_debug("Flushing... ");
|
||||
if (exfat_fsync(dev) != 0)
|
||||
return 1;
|
||||
//puts("done.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
off_t get_position(const struct fs_object* object)
|
||||
{
|
||||
const struct fs_object** pp;
|
||||
off_t position = 0;
|
||||
|
||||
for (pp = objects; *pp; pp++)
|
||||
{
|
||||
position = ROUND_UP(position, (*pp)->get_alignment());
|
||||
if (*pp == object)
|
||||
return position;
|
||||
position += (*pp)->get_size();
|
||||
}
|
||||
exfat_bug("unknown object");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
49
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h
Normal file
49
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
mkexfat.h (09.11.10)
|
||||
FS creation engine.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_MKEXFAT_H_INCLUDED
|
||||
#define MKFS_MKEXFAT_H_INCLUDED
|
||||
|
||||
#include "exfat.h"
|
||||
|
||||
struct fs_object
|
||||
{
|
||||
off_t (*get_alignment)(void);
|
||||
off_t (*get_size)(void);
|
||||
int (*write)(struct exfat_dev* dev);
|
||||
};
|
||||
|
||||
extern const struct fs_object* objects[];
|
||||
|
||||
int get_sector_bits(void);
|
||||
int get_spc_bits(void);
|
||||
off_t get_volume_size(void);
|
||||
const le16_t* get_volume_label(void);
|
||||
uint32_t get_volume_serial(void);
|
||||
uint64_t get_first_sector(void);
|
||||
int get_sector_size(void);
|
||||
int get_cluster_size(void);
|
||||
|
||||
int mkfs(struct exfat_dev* dev, off_t volume_size);
|
||||
off_t get_position(const struct fs_object* object);
|
||||
|
||||
#endif /* ifndef MKFS_MKEXFAT_H_INCLUDED */
|
268
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c
Normal file
268
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
main.c (15.08.10)
|
||||
Creates exFAT file system.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "mkexfat.h"
|
||||
#include "vbr.h"
|
||||
#include "fat.h"
|
||||
#include "cbm.h"
|
||||
#include "uct.h"
|
||||
#include "rootdir.h"
|
||||
#include "exfat.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
const struct fs_object* objects[] =
|
||||
{
|
||||
&vbr,
|
||||
&vbr,
|
||||
&fat,
|
||||
/* clusters heap */
|
||||
&cbm,
|
||||
&uct,
|
||||
&rootdir,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
int sector_bits;
|
||||
int spc_bits;
|
||||
off_t volume_size;
|
||||
le16_t volume_label[EXFAT_ENAME_MAX + 1];
|
||||
uint32_t volume_serial;
|
||||
uint64_t first_sector;
|
||||
}
|
||||
param;
|
||||
|
||||
extern int g_vtoy_exfat_disk_fd;
|
||||
extern uint64_t g_vtoy_exfat_part_size;
|
||||
|
||||
int get_sector_bits(void)
|
||||
{
|
||||
return param.sector_bits;
|
||||
}
|
||||
|
||||
int get_spc_bits(void)
|
||||
{
|
||||
return param.spc_bits;
|
||||
}
|
||||
|
||||
off_t get_volume_size(void)
|
||||
{
|
||||
return param.volume_size;
|
||||
}
|
||||
|
||||
const le16_t* get_volume_label(void)
|
||||
{
|
||||
return param.volume_label;
|
||||
}
|
||||
|
||||
uint32_t get_volume_serial(void)
|
||||
{
|
||||
return param.volume_serial;
|
||||
}
|
||||
|
||||
uint64_t get_first_sector(void)
|
||||
{
|
||||
return param.first_sector;
|
||||
}
|
||||
|
||||
int get_sector_size(void)
|
||||
{
|
||||
return 1 << get_sector_bits();
|
||||
}
|
||||
|
||||
int get_cluster_size(void)
|
||||
{
|
||||
return get_sector_size() << get_spc_bits();
|
||||
}
|
||||
|
||||
static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (user_defined != -1)
|
||||
{
|
||||
off_t cluster_size = 1 << sector_bits << user_defined;
|
||||
if (volume_size / cluster_size > EXFAT_LAST_DATA_CLUSTER)
|
||||
{
|
||||
struct exfat_human_bytes chb, vhb;
|
||||
|
||||
exfat_humanize_bytes(cluster_size, &chb);
|
||||
exfat_humanize_bytes(volume_size, &vhb);
|
||||
exfat_error("cluster size %"PRIu64" %s is too small for "
|
||||
"%"PRIu64" %s volume, try -s %d",
|
||||
chb.value, chb.unit,
|
||||
vhb.value, vhb.unit,
|
||||
1 << setup_spc_bits(sector_bits, -1, volume_size));
|
||||
return -1;
|
||||
}
|
||||
return user_defined;
|
||||
}
|
||||
|
||||
if (volume_size < 256ull * 1024 * 1024)
|
||||
return MAX(0, 12 - sector_bits); /* 4 KB */
|
||||
if (volume_size < 32ull * 1024 * 1024 * 1024)
|
||||
return MAX(0, 15 - sector_bits); /* 32 KB */
|
||||
|
||||
for (i = 17; ; i++) /* 128 KB or more */
|
||||
if (DIV_ROUND_UP(volume_size, 1 << i) <= EXFAT_LAST_DATA_CLUSTER)
|
||||
return MAX(0, i - sector_bits);
|
||||
}
|
||||
|
||||
static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s)
|
||||
{
|
||||
memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t));
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s));
|
||||
}
|
||||
|
||||
static uint32_t setup_volume_serial(uint32_t user_defined)
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
if (user_defined != 0)
|
||||
return user_defined;
|
||||
|
||||
if (gettimeofday(&now, NULL) != 0)
|
||||
{
|
||||
exfat_error("failed to form volume id");
|
||||
return 0;
|
||||
}
|
||||
return (now.tv_sec << 20) | now.tv_usec;
|
||||
}
|
||||
|
||||
static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits,
|
||||
const char* volume_label, uint32_t volume_serial,
|
||||
uint64_t first_sector)
|
||||
{
|
||||
param.sector_bits = sector_bits;
|
||||
param.first_sector = first_sector;
|
||||
param.volume_size = exfat_get_size(dev);
|
||||
|
||||
param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size);
|
||||
if (param.spc_bits == -1)
|
||||
return 1;
|
||||
|
||||
if (setup_volume_label(param.volume_label, volume_label) != 0)
|
||||
return 1;
|
||||
|
||||
param.volume_serial = setup_volume_serial(volume_serial);
|
||||
if (param.volume_serial == 0)
|
||||
return 1;
|
||||
|
||||
return mkfs(dev, param.volume_size);
|
||||
}
|
||||
|
||||
static int logarithm2(int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(int) * CHAR_BIT - 1; i++)
|
||||
if ((1 << i) == n)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void usage(const char* prog)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-i volume-id] [-n label] "
|
||||
"[-p partition-first-sector] "
|
||||
"[-s sectors-per-cluster] [-V] <device>\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int mkexfat_main(const char *devpath, int fd, uint64_t part_sector_count)
|
||||
{
|
||||
int spc_bits = -1;
|
||||
uint32_t volume_serial = 0;
|
||||
uint64_t first_sector = 0;
|
||||
struct exfat_dev* dev;
|
||||
|
||||
#if 0
|
||||
while ((opt = getopt(argc, argv, "i:n:p:s:V")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'i':
|
||||
volume_serial = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'n':
|
||||
volume_label = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
first_sector = strtoll(optarg, NULL, 10);
|
||||
break;
|
||||
case 's':
|
||||
spc_bits = logarithm2(atoi(optarg));
|
||||
if (spc_bits < 0)
|
||||
{
|
||||
exfat_error("invalid option value: '%s'", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
puts("Copyright (C) 2011-2018 Andrew Nayenko");
|
||||
return 0;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* #if 0 */
|
||||
|
||||
/*
|
||||
* DiskSize > 32GB Cluster Size use 128KB
|
||||
* DiskSize < 32GB Cluster Size use 32KB
|
||||
*/
|
||||
if ((part_sector_count / 2097152) > 32)
|
||||
{
|
||||
spc_bits = logarithm2(256);
|
||||
}
|
||||
else
|
||||
{
|
||||
spc_bits = logarithm2(64);
|
||||
}
|
||||
|
||||
g_vtoy_exfat_disk_fd = fd;
|
||||
g_vtoy_exfat_part_size = part_sector_count * 512;
|
||||
|
||||
dev = exfat_open(devpath, EXFAT_MODE_RW);
|
||||
if (dev == NULL)
|
||||
return 1;
|
||||
if (setup(dev, 9, spc_bits, "Ventoy", volume_serial, first_sector) != 0)
|
||||
{
|
||||
exfat_close(dev);
|
||||
return 1;
|
||||
}
|
||||
if (exfat_close(dev) != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
102
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c
Normal file
102
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
rootdir.c (09.11.10)
|
||||
Root directory creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "rootdir.h"
|
||||
#include "uct.h"
|
||||
#include "cbm.h"
|
||||
#include "uctc.h"
|
||||
#include <string.h>
|
||||
|
||||
static off_t rootdir_alignment(void)
|
||||
{
|
||||
return get_cluster_size();
|
||||
}
|
||||
|
||||
static off_t rootdir_size(void)
|
||||
{
|
||||
return get_cluster_size();
|
||||
}
|
||||
|
||||
static void init_label_entry(struct exfat_entry_label* label_entry)
|
||||
{
|
||||
memset(label_entry, 0, sizeof(struct exfat_entry_label));
|
||||
label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID;
|
||||
|
||||
if (utf16_length(get_volume_label()) == 0)
|
||||
return;
|
||||
|
||||
memcpy(label_entry->name, get_volume_label(),
|
||||
EXFAT_ENAME_MAX * sizeof(le16_t));
|
||||
label_entry->length = utf16_length(get_volume_label());
|
||||
label_entry->type |= EXFAT_ENTRY_VALID;
|
||||
}
|
||||
|
||||
static void init_bitmap_entry(struct exfat_entry_bitmap* bitmap_entry)
|
||||
{
|
||||
memset(bitmap_entry, 0, sizeof(struct exfat_entry_bitmap));
|
||||
bitmap_entry->type = EXFAT_ENTRY_BITMAP;
|
||||
bitmap_entry->start_cluster = cpu_to_le32(EXFAT_FIRST_DATA_CLUSTER);
|
||||
bitmap_entry->size = cpu_to_le64(cbm.get_size());
|
||||
}
|
||||
|
||||
static void init_upcase_entry(struct exfat_entry_upcase* upcase_entry)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (i = 0; i < sizeof(upcase_table); i++)
|
||||
sum = ((sum << 31) | (sum >> 1)) + upcase_table[i];
|
||||
|
||||
memset(upcase_entry, 0, sizeof(struct exfat_entry_upcase));
|
||||
upcase_entry->type = EXFAT_ENTRY_UPCASE;
|
||||
upcase_entry->checksum = cpu_to_le32(sum);
|
||||
upcase_entry->start_cluster = cpu_to_le32(
|
||||
(get_position(&uct) - get_position(&cbm)) / get_cluster_size() +
|
||||
EXFAT_FIRST_DATA_CLUSTER);
|
||||
upcase_entry->size = cpu_to_le64(sizeof(upcase_table));
|
||||
}
|
||||
|
||||
static int rootdir_write(struct exfat_dev* dev)
|
||||
{
|
||||
struct exfat_entry_label label_entry;
|
||||
struct exfat_entry_bitmap bitmap_entry;
|
||||
struct exfat_entry_upcase upcase_entry;
|
||||
|
||||
init_label_entry(&label_entry);
|
||||
init_bitmap_entry(&bitmap_entry);
|
||||
init_upcase_entry(&upcase_entry);
|
||||
|
||||
if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0)
|
||||
return 1;
|
||||
if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0)
|
||||
return 1;
|
||||
if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fs_object rootdir =
|
||||
{
|
||||
.get_alignment = rootdir_alignment,
|
||||
.get_size = rootdir_size,
|
||||
.write = rootdir_write,
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
rootdir.h (09.11.10)
|
||||
Root directory creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_ROOTDIR_H_INCLUDED
|
||||
#define MKFS_ROOTDIR_H_INCLUDED
|
||||
|
||||
#include "mkexfat.h"
|
||||
|
||||
extern const struct fs_object rootdir;
|
||||
|
||||
#endif /* ifndef MKFS_ROOTDIR_H_INCLUDED */
|
52
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c
Normal file
52
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
uct.c (09.11.10)
|
||||
Upper Case Table creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "uct.h"
|
||||
#include "uctc.h"
|
||||
|
||||
static off_t uct_alignment(void)
|
||||
{
|
||||
return get_cluster_size();
|
||||
}
|
||||
|
||||
static off_t uct_size(void)
|
||||
{
|
||||
return sizeof(upcase_table);
|
||||
}
|
||||
|
||||
static int uct_write(struct exfat_dev* dev)
|
||||
{
|
||||
if (exfat_write(dev, upcase_table, sizeof(upcase_table)) < 0)
|
||||
{
|
||||
exfat_error("failed to write upcase table of %zu bytes",
|
||||
sizeof(upcase_table));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fs_object uct =
|
||||
{
|
||||
.get_alignment = uct_alignment,
|
||||
.get_size = uct_size,
|
||||
.write = uct_write,
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
uct.h (09.11.10)
|
||||
Upper Case Table creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_UCT_H_INCLUDED
|
||||
#define MKFS_UCT_H_INCLUDED
|
||||
|
||||
#include "mkexfat.h"
|
||||
|
||||
extern const struct fs_object uct;
|
||||
|
||||
#endif /* ifndef MKFS_UCT_H_INCLUDED */
|
757
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c
Normal file
757
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c
Normal file
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
uctc.c (30.04.12)
|
||||
Upper Case Table contents.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "uctc.h"
|
||||
|
||||
uint8_t upcase_table[5836] =
|
||||
{
|
||||
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00,
|
||||
0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
|
||||
0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00,
|
||||
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00,
|
||||
0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00,
|
||||
0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
|
||||
0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00,
|
||||
0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00,
|
||||
0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00,
|
||||
0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00,
|
||||
0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00,
|
||||
0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00,
|
||||
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00,
|
||||
0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
|
||||
0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00,
|
||||
0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
|
||||
0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00,
|
||||
0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00,
|
||||
0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00,
|
||||
0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00,
|
||||
0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00,
|
||||
0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00,
|
||||
0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00,
|
||||
0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00,
|
||||
0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00,
|
||||
0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00,
|
||||
0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00,
|
||||
0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00,
|
||||
0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00,
|
||||
0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00,
|
||||
0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x7b, 0x00,
|
||||
0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00,
|
||||
0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00,
|
||||
0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00,
|
||||
0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00,
|
||||
0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00,
|
||||
0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00,
|
||||
0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00,
|
||||
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x00,
|
||||
0x9c, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0x9f, 0x00,
|
||||
0xa0, 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00,
|
||||
0xa4, 0x00, 0xa5, 0x00, 0xa6, 0x00, 0xa7, 0x00,
|
||||
0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xab, 0x00,
|
||||
0xac, 0x00, 0xad, 0x00, 0xae, 0x00, 0xaf, 0x00,
|
||||
0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0x00,
|
||||
0xb4, 0x00, 0xb5, 0x00, 0xb6, 0x00, 0xb7, 0x00,
|
||||
0xb8, 0x00, 0xb9, 0x00, 0xba, 0x00, 0xbb, 0x00,
|
||||
0xbc, 0x00, 0xbd, 0x00, 0xbe, 0x00, 0xbf, 0x00,
|
||||
0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00,
|
||||
0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00,
|
||||
0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00,
|
||||
0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00,
|
||||
0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00,
|
||||
0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd7, 0x00,
|
||||
0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00,
|
||||
0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0xdf, 0x00,
|
||||
0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00,
|
||||
0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00,
|
||||
0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00,
|
||||
0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00,
|
||||
0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00,
|
||||
0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xf7, 0x00,
|
||||
0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00,
|
||||
0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0x78, 0x01,
|
||||
0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01,
|
||||
0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01,
|
||||
0x08, 0x01, 0x08, 0x01, 0x0a, 0x01, 0x0a, 0x01,
|
||||
0x0c, 0x01, 0x0c, 0x01, 0x0e, 0x01, 0x0e, 0x01,
|
||||
0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01,
|
||||
0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01,
|
||||
0x18, 0x01, 0x18, 0x01, 0x1a, 0x01, 0x1a, 0x01,
|
||||
0x1c, 0x01, 0x1c, 0x01, 0x1e, 0x01, 0x1e, 0x01,
|
||||
0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01,
|
||||
0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01,
|
||||
0x28, 0x01, 0x28, 0x01, 0x2a, 0x01, 0x2a, 0x01,
|
||||
0x2c, 0x01, 0x2c, 0x01, 0x2e, 0x01, 0x2e, 0x01,
|
||||
0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01,
|
||||
0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01,
|
||||
0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3b, 0x01,
|
||||
0x3b, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x3f, 0x01,
|
||||
0x3f, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01,
|
||||
0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01,
|
||||
0x47, 0x01, 0x49, 0x01, 0x4a, 0x01, 0x4a, 0x01,
|
||||
0x4c, 0x01, 0x4c, 0x01, 0x4e, 0x01, 0x4e, 0x01,
|
||||
0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01,
|
||||
0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01,
|
||||
0x58, 0x01, 0x58, 0x01, 0x5a, 0x01, 0x5a, 0x01,
|
||||
0x5c, 0x01, 0x5c, 0x01, 0x5e, 0x01, 0x5e, 0x01,
|
||||
0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01,
|
||||
0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01,
|
||||
0x68, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x6a, 0x01,
|
||||
0x6c, 0x01, 0x6c, 0x01, 0x6e, 0x01, 0x6e, 0x01,
|
||||
0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01,
|
||||
0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01,
|
||||
0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7b, 0x01,
|
||||
0x7b, 0x01, 0x7d, 0x01, 0x7d, 0x01, 0x7f, 0x01,
|
||||
0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01,
|
||||
0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01,
|
||||
0x87, 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01,
|
||||
0x8b, 0x01, 0x8d, 0x01, 0x8e, 0x01, 0x8f, 0x01,
|
||||
0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01,
|
||||
0x94, 0x01, 0xf6, 0x01, 0x96, 0x01, 0x97, 0x01,
|
||||
0x98, 0x01, 0x98, 0x01, 0x3d, 0x02, 0x9b, 0x01,
|
||||
0x9c, 0x01, 0x9d, 0x01, 0x20, 0x02, 0x9f, 0x01,
|
||||
0xa0, 0x01, 0xa0, 0x01, 0xa2, 0x01, 0xa2, 0x01,
|
||||
0xa4, 0x01, 0xa4, 0x01, 0xa6, 0x01, 0xa7, 0x01,
|
||||
0xa7, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, 0x01,
|
||||
0xac, 0x01, 0xac, 0x01, 0xae, 0x01, 0xaf, 0x01,
|
||||
0xaf, 0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01,
|
||||
0xb3, 0x01, 0xb5, 0x01, 0xb5, 0x01, 0xb7, 0x01,
|
||||
0xb8, 0x01, 0xb8, 0x01, 0xba, 0x01, 0xbb, 0x01,
|
||||
0xbc, 0x01, 0xbc, 0x01, 0xbe, 0x01, 0xf7, 0x01,
|
||||
0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01,
|
||||
0xc4, 0x01, 0xc5, 0x01, 0xc4, 0x01, 0xc7, 0x01,
|
||||
0xc8, 0x01, 0xc7, 0x01, 0xca, 0x01, 0xcb, 0x01,
|
||||
0xca, 0x01, 0xcd, 0x01, 0xcd, 0x01, 0xcf, 0x01,
|
||||
0xcf, 0x01, 0xd1, 0x01, 0xd1, 0x01, 0xd3, 0x01,
|
||||
0xd3, 0x01, 0xd5, 0x01, 0xd5, 0x01, 0xd7, 0x01,
|
||||
0xd7, 0x01, 0xd9, 0x01, 0xd9, 0x01, 0xdb, 0x01,
|
||||
0xdb, 0x01, 0x8e, 0x01, 0xde, 0x01, 0xde, 0x01,
|
||||
0xe0, 0x01, 0xe0, 0x01, 0xe2, 0x01, 0xe2, 0x01,
|
||||
0xe4, 0x01, 0xe4, 0x01, 0xe6, 0x01, 0xe6, 0x01,
|
||||
0xe8, 0x01, 0xe8, 0x01, 0xea, 0x01, 0xea, 0x01,
|
||||
0xec, 0x01, 0xec, 0x01, 0xee, 0x01, 0xee, 0x01,
|
||||
0xf0, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0xf1, 0x01,
|
||||
0xf4, 0x01, 0xf4, 0x01, 0xf6, 0x01, 0xf7, 0x01,
|
||||
0xf8, 0x01, 0xf8, 0x01, 0xfa, 0x01, 0xfa, 0x01,
|
||||
0xfc, 0x01, 0xfc, 0x01, 0xfe, 0x01, 0xfe, 0x01,
|
||||
0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02,
|
||||
0x08, 0x02, 0x08, 0x02, 0x0a, 0x02, 0x0a, 0x02,
|
||||
0x0c, 0x02, 0x0c, 0x02, 0x0e, 0x02, 0x0e, 0x02,
|
||||
0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02,
|
||||
0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02,
|
||||
0x18, 0x02, 0x18, 0x02, 0x1a, 0x02, 0x1a, 0x02,
|
||||
0x1c, 0x02, 0x1c, 0x02, 0x1e, 0x02, 0x1e, 0x02,
|
||||
0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02,
|
||||
0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02,
|
||||
0x28, 0x02, 0x28, 0x02, 0x2a, 0x02, 0x2a, 0x02,
|
||||
0x2c, 0x02, 0x2c, 0x02, 0x2e, 0x02, 0x2e, 0x02,
|
||||
0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02,
|
||||
0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02,
|
||||
0x38, 0x02, 0x39, 0x02, 0x65, 0x2c, 0x3b, 0x02,
|
||||
0x3b, 0x02, 0x3d, 0x02, 0x66, 0x2c, 0x3f, 0x02,
|
||||
0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02,
|
||||
0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02,
|
||||
0x48, 0x02, 0x48, 0x02, 0x4a, 0x02, 0x4a, 0x02,
|
||||
0x4c, 0x02, 0x4c, 0x02, 0x4e, 0x02, 0x4e, 0x02,
|
||||
0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01,
|
||||
0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8a, 0x01,
|
||||
0x58, 0x02, 0x8f, 0x01, 0x5a, 0x02, 0x90, 0x01,
|
||||
0x5c, 0x02, 0x5d, 0x02, 0x5e, 0x02, 0x5f, 0x02,
|
||||
0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01,
|
||||
0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02,
|
||||
0x97, 0x01, 0x96, 0x01, 0x6a, 0x02, 0x62, 0x2c,
|
||||
0x6c, 0x02, 0x6d, 0x02, 0x6e, 0x02, 0x9c, 0x01,
|
||||
0x70, 0x02, 0x71, 0x02, 0x9d, 0x01, 0x73, 0x02,
|
||||
0x74, 0x02, 0x9f, 0x01, 0x76, 0x02, 0x77, 0x02,
|
||||
0x78, 0x02, 0x79, 0x02, 0x7a, 0x02, 0x7b, 0x02,
|
||||
0x7c, 0x02, 0x64, 0x2c, 0x7e, 0x02, 0x7f, 0x02,
|
||||
0xa6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xa9, 0x01,
|
||||
0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02,
|
||||
0xae, 0x01, 0x44, 0x02, 0xb1, 0x01, 0xb2, 0x01,
|
||||
0x45, 0x02, 0x8d, 0x02, 0x8e, 0x02, 0x8f, 0x02,
|
||||
0x90, 0x02, 0x91, 0x02, 0xb7, 0x01, 0x93, 0x02,
|
||||
0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02,
|
||||
0x98, 0x02, 0x99, 0x02, 0x9a, 0x02, 0x9b, 0x02,
|
||||
0x9c, 0x02, 0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x02,
|
||||
0xa0, 0x02, 0xa1, 0x02, 0xa2, 0x02, 0xa3, 0x02,
|
||||
0xa4, 0x02, 0xa5, 0x02, 0xa6, 0x02, 0xa7, 0x02,
|
||||
0xa8, 0x02, 0xa9, 0x02, 0xaa, 0x02, 0xab, 0x02,
|
||||
0xac, 0x02, 0xad, 0x02, 0xae, 0x02, 0xaf, 0x02,
|
||||
0xb0, 0x02, 0xb1, 0x02, 0xb2, 0x02, 0xb3, 0x02,
|
||||
0xb4, 0x02, 0xb5, 0x02, 0xb6, 0x02, 0xb7, 0x02,
|
||||
0xb8, 0x02, 0xb9, 0x02, 0xba, 0x02, 0xbb, 0x02,
|
||||
0xbc, 0x02, 0xbd, 0x02, 0xbe, 0x02, 0xbf, 0x02,
|
||||
0xc0, 0x02, 0xc1, 0x02, 0xc2, 0x02, 0xc3, 0x02,
|
||||
0xc4, 0x02, 0xc5, 0x02, 0xc6, 0x02, 0xc7, 0x02,
|
||||
0xc8, 0x02, 0xc9, 0x02, 0xca, 0x02, 0xcb, 0x02,
|
||||
0xcc, 0x02, 0xcd, 0x02, 0xce, 0x02, 0xcf, 0x02,
|
||||
0xd0, 0x02, 0xd1, 0x02, 0xd2, 0x02, 0xd3, 0x02,
|
||||
0xd4, 0x02, 0xd5, 0x02, 0xd6, 0x02, 0xd7, 0x02,
|
||||
0xd8, 0x02, 0xd9, 0x02, 0xda, 0x02, 0xdb, 0x02,
|
||||
0xdc, 0x02, 0xdd, 0x02, 0xde, 0x02, 0xdf, 0x02,
|
||||
0xe0, 0x02, 0xe1, 0x02, 0xe2, 0x02, 0xe3, 0x02,
|
||||
0xe4, 0x02, 0xe5, 0x02, 0xe6, 0x02, 0xe7, 0x02,
|
||||
0xe8, 0x02, 0xe9, 0x02, 0xea, 0x02, 0xeb, 0x02,
|
||||
0xec, 0x02, 0xed, 0x02, 0xee, 0x02, 0xef, 0x02,
|
||||
0xf0, 0x02, 0xf1, 0x02, 0xf2, 0x02, 0xf3, 0x02,
|
||||
0xf4, 0x02, 0xf5, 0x02, 0xf6, 0x02, 0xf7, 0x02,
|
||||
0xf8, 0x02, 0xf9, 0x02, 0xfa, 0x02, 0xfb, 0x02,
|
||||
0xfc, 0x02, 0xfd, 0x02, 0xfe, 0x02, 0xff, 0x02,
|
||||
0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03,
|
||||
0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03,
|
||||
0x08, 0x03, 0x09, 0x03, 0x0a, 0x03, 0x0b, 0x03,
|
||||
0x0c, 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, 0x03,
|
||||
0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03,
|
||||
0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03,
|
||||
0x18, 0x03, 0x19, 0x03, 0x1a, 0x03, 0x1b, 0x03,
|
||||
0x1c, 0x03, 0x1d, 0x03, 0x1e, 0x03, 0x1f, 0x03,
|
||||
0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03,
|
||||
0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03,
|
||||
0x28, 0x03, 0x29, 0x03, 0x2a, 0x03, 0x2b, 0x03,
|
||||
0x2c, 0x03, 0x2d, 0x03, 0x2e, 0x03, 0x2f, 0x03,
|
||||
0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03,
|
||||
0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03,
|
||||
0x38, 0x03, 0x39, 0x03, 0x3a, 0x03, 0x3b, 0x03,
|
||||
0x3c, 0x03, 0x3d, 0x03, 0x3e, 0x03, 0x3f, 0x03,
|
||||
0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03,
|
||||
0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03,
|
||||
0x48, 0x03, 0x49, 0x03, 0x4a, 0x03, 0x4b, 0x03,
|
||||
0x4c, 0x03, 0x4d, 0x03, 0x4e, 0x03, 0x4f, 0x03,
|
||||
0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03,
|
||||
0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03,
|
||||
0x58, 0x03, 0x59, 0x03, 0x5a, 0x03, 0x5b, 0x03,
|
||||
0x5c, 0x03, 0x5d, 0x03, 0x5e, 0x03, 0x5f, 0x03,
|
||||
0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03,
|
||||
0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03,
|
||||
0x68, 0x03, 0x69, 0x03, 0x6a, 0x03, 0x6b, 0x03,
|
||||
0x6c, 0x03, 0x6d, 0x03, 0x6e, 0x03, 0x6f, 0x03,
|
||||
0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03,
|
||||
0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03,
|
||||
0x78, 0x03, 0x79, 0x03, 0x7a, 0x03, 0xfd, 0x03,
|
||||
0xfe, 0x03, 0xff, 0x03, 0x7e, 0x03, 0x7f, 0x03,
|
||||
0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03,
|
||||
0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03,
|
||||
0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, 0x8b, 0x03,
|
||||
0x8c, 0x03, 0x8d, 0x03, 0x8e, 0x03, 0x8f, 0x03,
|
||||
0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03,
|
||||
0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03,
|
||||
0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03,
|
||||
0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03,
|
||||
0xa0, 0x03, 0xa1, 0x03, 0xa2, 0x03, 0xa3, 0x03,
|
||||
0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03,
|
||||
0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03,
|
||||
0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03,
|
||||
0xb0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03,
|
||||
0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03,
|
||||
0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03,
|
||||
0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03,
|
||||
0xa0, 0x03, 0xa1, 0x03, 0xa3, 0x03, 0xa3, 0x03,
|
||||
0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03,
|
||||
0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03,
|
||||
0x8c, 0x03, 0x8e, 0x03, 0x8f, 0x03, 0xcf, 0x03,
|
||||
0xd0, 0x03, 0xd1, 0x03, 0xd2, 0x03, 0xd3, 0x03,
|
||||
0xd4, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd7, 0x03,
|
||||
0xd8, 0x03, 0xd8, 0x03, 0xda, 0x03, 0xda, 0x03,
|
||||
0xdc, 0x03, 0xdc, 0x03, 0xde, 0x03, 0xde, 0x03,
|
||||
0xe0, 0x03, 0xe0, 0x03, 0xe2, 0x03, 0xe2, 0x03,
|
||||
0xe4, 0x03, 0xe4, 0x03, 0xe6, 0x03, 0xe6, 0x03,
|
||||
0xe8, 0x03, 0xe8, 0x03, 0xea, 0x03, 0xea, 0x03,
|
||||
0xec, 0x03, 0xec, 0x03, 0xee, 0x03, 0xee, 0x03,
|
||||
0xf0, 0x03, 0xf1, 0x03, 0xf9, 0x03, 0xf3, 0x03,
|
||||
0xf4, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf7, 0x03,
|
||||
0xf7, 0x03, 0xf9, 0x03, 0xfa, 0x03, 0xfa, 0x03,
|
||||
0xfc, 0x03, 0xfd, 0x03, 0xfe, 0x03, 0xff, 0x03,
|
||||
0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04,
|
||||
0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04,
|
||||
0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04,
|
||||
0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04,
|
||||
0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04,
|
||||
0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04,
|
||||
0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04,
|
||||
0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04,
|
||||
0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04,
|
||||
0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04,
|
||||
0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04,
|
||||
0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04,
|
||||
0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04,
|
||||
0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04,
|
||||
0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04,
|
||||
0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04,
|
||||
0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04,
|
||||
0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04,
|
||||
0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04,
|
||||
0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04,
|
||||
0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04,
|
||||
0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04,
|
||||
0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04,
|
||||
0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04,
|
||||
0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04,
|
||||
0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04,
|
||||
0x68, 0x04, 0x68, 0x04, 0x6a, 0x04, 0x6a, 0x04,
|
||||
0x6c, 0x04, 0x6c, 0x04, 0x6e, 0x04, 0x6e, 0x04,
|
||||
0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04,
|
||||
0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04,
|
||||
0x78, 0x04, 0x78, 0x04, 0x7a, 0x04, 0x7a, 0x04,
|
||||
0x7c, 0x04, 0x7c, 0x04, 0x7e, 0x04, 0x7e, 0x04,
|
||||
0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04,
|
||||
0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04,
|
||||
0x88, 0x04, 0x89, 0x04, 0x8a, 0x04, 0x8a, 0x04,
|
||||
0x8c, 0x04, 0x8c, 0x04, 0x8e, 0x04, 0x8e, 0x04,
|
||||
0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04,
|
||||
0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04,
|
||||
0x98, 0x04, 0x98, 0x04, 0x9a, 0x04, 0x9a, 0x04,
|
||||
0x9c, 0x04, 0x9c, 0x04, 0x9e, 0x04, 0x9e, 0x04,
|
||||
0xa0, 0x04, 0xa0, 0x04, 0xa2, 0x04, 0xa2, 0x04,
|
||||
0xa4, 0x04, 0xa4, 0x04, 0xa6, 0x04, 0xa6, 0x04,
|
||||
0xa8, 0x04, 0xa8, 0x04, 0xaa, 0x04, 0xaa, 0x04,
|
||||
0xac, 0x04, 0xac, 0x04, 0xae, 0x04, 0xae, 0x04,
|
||||
0xb0, 0x04, 0xb0, 0x04, 0xb2, 0x04, 0xb2, 0x04,
|
||||
0xb4, 0x04, 0xb4, 0x04, 0xb6, 0x04, 0xb6, 0x04,
|
||||
0xb8, 0x04, 0xb8, 0x04, 0xba, 0x04, 0xba, 0x04,
|
||||
0xbc, 0x04, 0xbc, 0x04, 0xbe, 0x04, 0xbe, 0x04,
|
||||
0xc0, 0x04, 0xc1, 0x04, 0xc1, 0x04, 0xc3, 0x04,
|
||||
0xc3, 0x04, 0xc5, 0x04, 0xc5, 0x04, 0xc7, 0x04,
|
||||
0xc7, 0x04, 0xc9, 0x04, 0xc9, 0x04, 0xcb, 0x04,
|
||||
0xcb, 0x04, 0xcd, 0x04, 0xcd, 0x04, 0xc0, 0x04,
|
||||
0xd0, 0x04, 0xd0, 0x04, 0xd2, 0x04, 0xd2, 0x04,
|
||||
0xd4, 0x04, 0xd4, 0x04, 0xd6, 0x04, 0xd6, 0x04,
|
||||
0xd8, 0x04, 0xd8, 0x04, 0xda, 0x04, 0xda, 0x04,
|
||||
0xdc, 0x04, 0xdc, 0x04, 0xde, 0x04, 0xde, 0x04,
|
||||
0xe0, 0x04, 0xe0, 0x04, 0xe2, 0x04, 0xe2, 0x04,
|
||||
0xe4, 0x04, 0xe4, 0x04, 0xe6, 0x04, 0xe6, 0x04,
|
||||
0xe8, 0x04, 0xe8, 0x04, 0xea, 0x04, 0xea, 0x04,
|
||||
0xec, 0x04, 0xec, 0x04, 0xee, 0x04, 0xee, 0x04,
|
||||
0xf0, 0x04, 0xf0, 0x04, 0xf2, 0x04, 0xf2, 0x04,
|
||||
0xf4, 0x04, 0xf4, 0x04, 0xf6, 0x04, 0xf6, 0x04,
|
||||
0xf8, 0x04, 0xf8, 0x04, 0xfa, 0x04, 0xfa, 0x04,
|
||||
0xfc, 0x04, 0xfc, 0x04, 0xfe, 0x04, 0xfe, 0x04,
|
||||
0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05,
|
||||
0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05,
|
||||
0x08, 0x05, 0x08, 0x05, 0x0a, 0x05, 0x0a, 0x05,
|
||||
0x0c, 0x05, 0x0c, 0x05, 0x0e, 0x05, 0x0e, 0x05,
|
||||
0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05,
|
||||
0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05,
|
||||
0x18, 0x05, 0x19, 0x05, 0x1a, 0x05, 0x1b, 0x05,
|
||||
0x1c, 0x05, 0x1d, 0x05, 0x1e, 0x05, 0x1f, 0x05,
|
||||
0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05,
|
||||
0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05,
|
||||
0x28, 0x05, 0x29, 0x05, 0x2a, 0x05, 0x2b, 0x05,
|
||||
0x2c, 0x05, 0x2d, 0x05, 0x2e, 0x05, 0x2f, 0x05,
|
||||
0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05,
|
||||
0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05,
|
||||
0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05,
|
||||
0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05,
|
||||
0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05,
|
||||
0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05,
|
||||
0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05,
|
||||
0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05,
|
||||
0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05,
|
||||
0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05,
|
||||
0x58, 0x05, 0x59, 0x05, 0x5a, 0x05, 0x5b, 0x05,
|
||||
0x5c, 0x05, 0x5d, 0x05, 0x5e, 0x05, 0x5f, 0x05,
|
||||
0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05,
|
||||
0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05,
|
||||
0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05,
|
||||
0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05,
|
||||
0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05,
|
||||
0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05,
|
||||
0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05,
|
||||
0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05,
|
||||
0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05,
|
||||
0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xff, 0xff,
|
||||
0xf6, 0x17, 0x63, 0x2c, 0x7e, 0x1d, 0x7f, 0x1d,
|
||||
0x80, 0x1d, 0x81, 0x1d, 0x82, 0x1d, 0x83, 0x1d,
|
||||
0x84, 0x1d, 0x85, 0x1d, 0x86, 0x1d, 0x87, 0x1d,
|
||||
0x88, 0x1d, 0x89, 0x1d, 0x8a, 0x1d, 0x8b, 0x1d,
|
||||
0x8c, 0x1d, 0x8d, 0x1d, 0x8e, 0x1d, 0x8f, 0x1d,
|
||||
0x90, 0x1d, 0x91, 0x1d, 0x92, 0x1d, 0x93, 0x1d,
|
||||
0x94, 0x1d, 0x95, 0x1d, 0x96, 0x1d, 0x97, 0x1d,
|
||||
0x98, 0x1d, 0x99, 0x1d, 0x9a, 0x1d, 0x9b, 0x1d,
|
||||
0x9c, 0x1d, 0x9d, 0x1d, 0x9e, 0x1d, 0x9f, 0x1d,
|
||||
0xa0, 0x1d, 0xa1, 0x1d, 0xa2, 0x1d, 0xa3, 0x1d,
|
||||
0xa4, 0x1d, 0xa5, 0x1d, 0xa6, 0x1d, 0xa7, 0x1d,
|
||||
0xa8, 0x1d, 0xa9, 0x1d, 0xaa, 0x1d, 0xab, 0x1d,
|
||||
0xac, 0x1d, 0xad, 0x1d, 0xae, 0x1d, 0xaf, 0x1d,
|
||||
0xb0, 0x1d, 0xb1, 0x1d, 0xb2, 0x1d, 0xb3, 0x1d,
|
||||
0xb4, 0x1d, 0xb5, 0x1d, 0xb6, 0x1d, 0xb7, 0x1d,
|
||||
0xb8, 0x1d, 0xb9, 0x1d, 0xba, 0x1d, 0xbb, 0x1d,
|
||||
0xbc, 0x1d, 0xbd, 0x1d, 0xbe, 0x1d, 0xbf, 0x1d,
|
||||
0xc0, 0x1d, 0xc1, 0x1d, 0xc2, 0x1d, 0xc3, 0x1d,
|
||||
0xc4, 0x1d, 0xc5, 0x1d, 0xc6, 0x1d, 0xc7, 0x1d,
|
||||
0xc8, 0x1d, 0xc9, 0x1d, 0xca, 0x1d, 0xcb, 0x1d,
|
||||
0xcc, 0x1d, 0xcd, 0x1d, 0xce, 0x1d, 0xcf, 0x1d,
|
||||
0xd0, 0x1d, 0xd1, 0x1d, 0xd2, 0x1d, 0xd3, 0x1d,
|
||||
0xd4, 0x1d, 0xd5, 0x1d, 0xd6, 0x1d, 0xd7, 0x1d,
|
||||
0xd8, 0x1d, 0xd9, 0x1d, 0xda, 0x1d, 0xdb, 0x1d,
|
||||
0xdc, 0x1d, 0xdd, 0x1d, 0xde, 0x1d, 0xdf, 0x1d,
|
||||
0xe0, 0x1d, 0xe1, 0x1d, 0xe2, 0x1d, 0xe3, 0x1d,
|
||||
0xe4, 0x1d, 0xe5, 0x1d, 0xe6, 0x1d, 0xe7, 0x1d,
|
||||
0xe8, 0x1d, 0xe9, 0x1d, 0xea, 0x1d, 0xeb, 0x1d,
|
||||
0xec, 0x1d, 0xed, 0x1d, 0xee, 0x1d, 0xef, 0x1d,
|
||||
0xf0, 0x1d, 0xf1, 0x1d, 0xf2, 0x1d, 0xf3, 0x1d,
|
||||
0xf4, 0x1d, 0xf5, 0x1d, 0xf6, 0x1d, 0xf7, 0x1d,
|
||||
0xf8, 0x1d, 0xf9, 0x1d, 0xfa, 0x1d, 0xfb, 0x1d,
|
||||
0xfc, 0x1d, 0xfd, 0x1d, 0xfe, 0x1d, 0xff, 0x1d,
|
||||
0x00, 0x1e, 0x00, 0x1e, 0x02, 0x1e, 0x02, 0x1e,
|
||||
0x04, 0x1e, 0x04, 0x1e, 0x06, 0x1e, 0x06, 0x1e,
|
||||
0x08, 0x1e, 0x08, 0x1e, 0x0a, 0x1e, 0x0a, 0x1e,
|
||||
0x0c, 0x1e, 0x0c, 0x1e, 0x0e, 0x1e, 0x0e, 0x1e,
|
||||
0x10, 0x1e, 0x10, 0x1e, 0x12, 0x1e, 0x12, 0x1e,
|
||||
0x14, 0x1e, 0x14, 0x1e, 0x16, 0x1e, 0x16, 0x1e,
|
||||
0x18, 0x1e, 0x18, 0x1e, 0x1a, 0x1e, 0x1a, 0x1e,
|
||||
0x1c, 0x1e, 0x1c, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
||||
0x20, 0x1e, 0x20, 0x1e, 0x22, 0x1e, 0x22, 0x1e,
|
||||
0x24, 0x1e, 0x24, 0x1e, 0x26, 0x1e, 0x26, 0x1e,
|
||||
0x28, 0x1e, 0x28, 0x1e, 0x2a, 0x1e, 0x2a, 0x1e,
|
||||
0x2c, 0x1e, 0x2c, 0x1e, 0x2e, 0x1e, 0x2e, 0x1e,
|
||||
0x30, 0x1e, 0x30, 0x1e, 0x32, 0x1e, 0x32, 0x1e,
|
||||
0x34, 0x1e, 0x34, 0x1e, 0x36, 0x1e, 0x36, 0x1e,
|
||||
0x38, 0x1e, 0x38, 0x1e, 0x3a, 0x1e, 0x3a, 0x1e,
|
||||
0x3c, 0x1e, 0x3c, 0x1e, 0x3e, 0x1e, 0x3e, 0x1e,
|
||||
0x40, 0x1e, 0x40, 0x1e, 0x42, 0x1e, 0x42, 0x1e,
|
||||
0x44, 0x1e, 0x44, 0x1e, 0x46, 0x1e, 0x46, 0x1e,
|
||||
0x48, 0x1e, 0x48, 0x1e, 0x4a, 0x1e, 0x4a, 0x1e,
|
||||
0x4c, 0x1e, 0x4c, 0x1e, 0x4e, 0x1e, 0x4e, 0x1e,
|
||||
0x50, 0x1e, 0x50, 0x1e, 0x52, 0x1e, 0x52, 0x1e,
|
||||
0x54, 0x1e, 0x54, 0x1e, 0x56, 0x1e, 0x56, 0x1e,
|
||||
0x58, 0x1e, 0x58, 0x1e, 0x5a, 0x1e, 0x5a, 0x1e,
|
||||
0x5c, 0x1e, 0x5c, 0x1e, 0x5e, 0x1e, 0x5e, 0x1e,
|
||||
0x60, 0x1e, 0x60, 0x1e, 0x62, 0x1e, 0x62, 0x1e,
|
||||
0x64, 0x1e, 0x64, 0x1e, 0x66, 0x1e, 0x66, 0x1e,
|
||||
0x68, 0x1e, 0x68, 0x1e, 0x6a, 0x1e, 0x6a, 0x1e,
|
||||
0x6c, 0x1e, 0x6c, 0x1e, 0x6e, 0x1e, 0x6e, 0x1e,
|
||||
0x70, 0x1e, 0x70, 0x1e, 0x72, 0x1e, 0x72, 0x1e,
|
||||
0x74, 0x1e, 0x74, 0x1e, 0x76, 0x1e, 0x76, 0x1e,
|
||||
0x78, 0x1e, 0x78, 0x1e, 0x7a, 0x1e, 0x7a, 0x1e,
|
||||
0x7c, 0x1e, 0x7c, 0x1e, 0x7e, 0x1e, 0x7e, 0x1e,
|
||||
0x80, 0x1e, 0x80, 0x1e, 0x82, 0x1e, 0x82, 0x1e,
|
||||
0x84, 0x1e, 0x84, 0x1e, 0x86, 0x1e, 0x86, 0x1e,
|
||||
0x88, 0x1e, 0x88, 0x1e, 0x8a, 0x1e, 0x8a, 0x1e,
|
||||
0x8c, 0x1e, 0x8c, 0x1e, 0x8e, 0x1e, 0x8e, 0x1e,
|
||||
0x90, 0x1e, 0x90, 0x1e, 0x92, 0x1e, 0x92, 0x1e,
|
||||
0x94, 0x1e, 0x94, 0x1e, 0x96, 0x1e, 0x97, 0x1e,
|
||||
0x98, 0x1e, 0x99, 0x1e, 0x9a, 0x1e, 0x9b, 0x1e,
|
||||
0x9c, 0x1e, 0x9d, 0x1e, 0x9e, 0x1e, 0x9f, 0x1e,
|
||||
0xa0, 0x1e, 0xa0, 0x1e, 0xa2, 0x1e, 0xa2, 0x1e,
|
||||
0xa4, 0x1e, 0xa4, 0x1e, 0xa6, 0x1e, 0xa6, 0x1e,
|
||||
0xa8, 0x1e, 0xa8, 0x1e, 0xaa, 0x1e, 0xaa, 0x1e,
|
||||
0xac, 0x1e, 0xac, 0x1e, 0xae, 0x1e, 0xae, 0x1e,
|
||||
0xb0, 0x1e, 0xb0, 0x1e, 0xb2, 0x1e, 0xb2, 0x1e,
|
||||
0xb4, 0x1e, 0xb4, 0x1e, 0xb6, 0x1e, 0xb6, 0x1e,
|
||||
0xb8, 0x1e, 0xb8, 0x1e, 0xba, 0x1e, 0xba, 0x1e,
|
||||
0xbc, 0x1e, 0xbc, 0x1e, 0xbe, 0x1e, 0xbe, 0x1e,
|
||||
0xc0, 0x1e, 0xc0, 0x1e, 0xc2, 0x1e, 0xc2, 0x1e,
|
||||
0xc4, 0x1e, 0xc4, 0x1e, 0xc6, 0x1e, 0xc6, 0x1e,
|
||||
0xc8, 0x1e, 0xc8, 0x1e, 0xca, 0x1e, 0xca, 0x1e,
|
||||
0xcc, 0x1e, 0xcc, 0x1e, 0xce, 0x1e, 0xce, 0x1e,
|
||||
0xd0, 0x1e, 0xd0, 0x1e, 0xd2, 0x1e, 0xd2, 0x1e,
|
||||
0xd4, 0x1e, 0xd4, 0x1e, 0xd6, 0x1e, 0xd6, 0x1e,
|
||||
0xd8, 0x1e, 0xd8, 0x1e, 0xda, 0x1e, 0xda, 0x1e,
|
||||
0xdc, 0x1e, 0xdc, 0x1e, 0xde, 0x1e, 0xde, 0x1e,
|
||||
0xe0, 0x1e, 0xe0, 0x1e, 0xe2, 0x1e, 0xe2, 0x1e,
|
||||
0xe4, 0x1e, 0xe4, 0x1e, 0xe6, 0x1e, 0xe6, 0x1e,
|
||||
0xe8, 0x1e, 0xe8, 0x1e, 0xea, 0x1e, 0xea, 0x1e,
|
||||
0xec, 0x1e, 0xec, 0x1e, 0xee, 0x1e, 0xee, 0x1e,
|
||||
0xf0, 0x1e, 0xf0, 0x1e, 0xf2, 0x1e, 0xf2, 0x1e,
|
||||
0xf4, 0x1e, 0xf4, 0x1e, 0xf6, 0x1e, 0xf6, 0x1e,
|
||||
0xf8, 0x1e, 0xf8, 0x1e, 0xfa, 0x1e, 0xfb, 0x1e,
|
||||
0xfc, 0x1e, 0xfd, 0x1e, 0xfe, 0x1e, 0xff, 0x1e,
|
||||
0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f,
|
||||
0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f,
|
||||
0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f,
|
||||
0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f,
|
||||
0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f,
|
||||
0x1c, 0x1f, 0x1d, 0x1f, 0x16, 0x1f, 0x17, 0x1f,
|
||||
0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f,
|
||||
0x1c, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1f, 0x1f,
|
||||
0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f,
|
||||
0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f,
|
||||
0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f,
|
||||
0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f,
|
||||
0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f,
|
||||
0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f,
|
||||
0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f,
|
||||
0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f,
|
||||
0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f,
|
||||
0x4c, 0x1f, 0x4d, 0x1f, 0x46, 0x1f, 0x47, 0x1f,
|
||||
0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f,
|
||||
0x4c, 0x1f, 0x4d, 0x1f, 0x4e, 0x1f, 0x4f, 0x1f,
|
||||
0x50, 0x1f, 0x59, 0x1f, 0x52, 0x1f, 0x5b, 0x1f,
|
||||
0x54, 0x1f, 0x5d, 0x1f, 0x56, 0x1f, 0x5f, 0x1f,
|
||||
0x58, 0x1f, 0x59, 0x1f, 0x5a, 0x1f, 0x5b, 0x1f,
|
||||
0x5c, 0x1f, 0x5d, 0x1f, 0x5e, 0x1f, 0x5f, 0x1f,
|
||||
0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f,
|
||||
0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f,
|
||||
0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f,
|
||||
0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f,
|
||||
0xba, 0x1f, 0xbb, 0x1f, 0xc8, 0x1f, 0xc9, 0x1f,
|
||||
0xca, 0x1f, 0xcb, 0x1f, 0xda, 0x1f, 0xdb, 0x1f,
|
||||
0xf8, 0x1f, 0xf9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f,
|
||||
0xfa, 0x1f, 0xfb, 0x1f, 0x7e, 0x1f, 0x7f, 0x1f,
|
||||
0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f,
|
||||
0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f,
|
||||
0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f,
|
||||
0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f,
|
||||
0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f,
|
||||
0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f,
|
||||
0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f,
|
||||
0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f,
|
||||
0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f,
|
||||
0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f,
|
||||
0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f,
|
||||
0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f,
|
||||
0xb8, 0x1f, 0xb9, 0x1f, 0xb2, 0x1f, 0xbc, 0x1f,
|
||||
0xb4, 0x1f, 0xb5, 0x1f, 0xb6, 0x1f, 0xb7, 0x1f,
|
||||
0xb8, 0x1f, 0xb9, 0x1f, 0xba, 0x1f, 0xbb, 0x1f,
|
||||
0xbc, 0x1f, 0xbd, 0x1f, 0xbe, 0x1f, 0xbf, 0x1f,
|
||||
0xc0, 0x1f, 0xc1, 0x1f, 0xc2, 0x1f, 0xc3, 0x1f,
|
||||
0xc4, 0x1f, 0xc5, 0x1f, 0xc6, 0x1f, 0xc7, 0x1f,
|
||||
0xc8, 0x1f, 0xc9, 0x1f, 0xca, 0x1f, 0xcb, 0x1f,
|
||||
0xc3, 0x1f, 0xcd, 0x1f, 0xce, 0x1f, 0xcf, 0x1f,
|
||||
0xd8, 0x1f, 0xd9, 0x1f, 0xd2, 0x1f, 0xd3, 0x1f,
|
||||
0xd4, 0x1f, 0xd5, 0x1f, 0xd6, 0x1f, 0xd7, 0x1f,
|
||||
0xd8, 0x1f, 0xd9, 0x1f, 0xda, 0x1f, 0xdb, 0x1f,
|
||||
0xdc, 0x1f, 0xdd, 0x1f, 0xde, 0x1f, 0xdf, 0x1f,
|
||||
0xe8, 0x1f, 0xe9, 0x1f, 0xe2, 0x1f, 0xe3, 0x1f,
|
||||
0xe4, 0x1f, 0xec, 0x1f, 0xe6, 0x1f, 0xe7, 0x1f,
|
||||
0xe8, 0x1f, 0xe9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f,
|
||||
0xec, 0x1f, 0xed, 0x1f, 0xee, 0x1f, 0xef, 0x1f,
|
||||
0xf0, 0x1f, 0xf1, 0x1f, 0xf2, 0x1f, 0xf3, 0x1f,
|
||||
0xf4, 0x1f, 0xf5, 0x1f, 0xf6, 0x1f, 0xf7, 0x1f,
|
||||
0xf8, 0x1f, 0xf9, 0x1f, 0xfa, 0x1f, 0xfb, 0x1f,
|
||||
0xf3, 0x1f, 0xfd, 0x1f, 0xfe, 0x1f, 0xff, 0x1f,
|
||||
0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20,
|
||||
0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20,
|
||||
0x08, 0x20, 0x09, 0x20, 0x0a, 0x20, 0x0b, 0x20,
|
||||
0x0c, 0x20, 0x0d, 0x20, 0x0e, 0x20, 0x0f, 0x20,
|
||||
0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20,
|
||||
0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20,
|
||||
0x18, 0x20, 0x19, 0x20, 0x1a, 0x20, 0x1b, 0x20,
|
||||
0x1c, 0x20, 0x1d, 0x20, 0x1e, 0x20, 0x1f, 0x20,
|
||||
0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20,
|
||||
0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20,
|
||||
0x28, 0x20, 0x29, 0x20, 0x2a, 0x20, 0x2b, 0x20,
|
||||
0x2c, 0x20, 0x2d, 0x20, 0x2e, 0x20, 0x2f, 0x20,
|
||||
0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20,
|
||||
0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20,
|
||||
0x38, 0x20, 0x39, 0x20, 0x3a, 0x20, 0x3b, 0x20,
|
||||
0x3c, 0x20, 0x3d, 0x20, 0x3e, 0x20, 0x3f, 0x20,
|
||||
0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20,
|
||||
0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20,
|
||||
0x48, 0x20, 0x49, 0x20, 0x4a, 0x20, 0x4b, 0x20,
|
||||
0x4c, 0x20, 0x4d, 0x20, 0x4e, 0x20, 0x4f, 0x20,
|
||||
0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20,
|
||||
0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20,
|
||||
0x58, 0x20, 0x59, 0x20, 0x5a, 0x20, 0x5b, 0x20,
|
||||
0x5c, 0x20, 0x5d, 0x20, 0x5e, 0x20, 0x5f, 0x20,
|
||||
0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20,
|
||||
0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20,
|
||||
0x68, 0x20, 0x69, 0x20, 0x6a, 0x20, 0x6b, 0x20,
|
||||
0x6c, 0x20, 0x6d, 0x20, 0x6e, 0x20, 0x6f, 0x20,
|
||||
0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20,
|
||||
0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20,
|
||||
0x78, 0x20, 0x79, 0x20, 0x7a, 0x20, 0x7b, 0x20,
|
||||
0x7c, 0x20, 0x7d, 0x20, 0x7e, 0x20, 0x7f, 0x20,
|
||||
0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20,
|
||||
0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20,
|
||||
0x88, 0x20, 0x89, 0x20, 0x8a, 0x20, 0x8b, 0x20,
|
||||
0x8c, 0x20, 0x8d, 0x20, 0x8e, 0x20, 0x8f, 0x20,
|
||||
0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20,
|
||||
0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20,
|
||||
0x98, 0x20, 0x99, 0x20, 0x9a, 0x20, 0x9b, 0x20,
|
||||
0x9c, 0x20, 0x9d, 0x20, 0x9e, 0x20, 0x9f, 0x20,
|
||||
0xa0, 0x20, 0xa1, 0x20, 0xa2, 0x20, 0xa3, 0x20,
|
||||
0xa4, 0x20, 0xa5, 0x20, 0xa6, 0x20, 0xa7, 0x20,
|
||||
0xa8, 0x20, 0xa9, 0x20, 0xaa, 0x20, 0xab, 0x20,
|
||||
0xac, 0x20, 0xad, 0x20, 0xae, 0x20, 0xaf, 0x20,
|
||||
0xb0, 0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20,
|
||||
0xb4, 0x20, 0xb5, 0x20, 0xb6, 0x20, 0xb7, 0x20,
|
||||
0xb8, 0x20, 0xb9, 0x20, 0xba, 0x20, 0xbb, 0x20,
|
||||
0xbc, 0x20, 0xbd, 0x20, 0xbe, 0x20, 0xbf, 0x20,
|
||||
0xc0, 0x20, 0xc1, 0x20, 0xc2, 0x20, 0xc3, 0x20,
|
||||
0xc4, 0x20, 0xc5, 0x20, 0xc6, 0x20, 0xc7, 0x20,
|
||||
0xc8, 0x20, 0xc9, 0x20, 0xca, 0x20, 0xcb, 0x20,
|
||||
0xcc, 0x20, 0xcd, 0x20, 0xce, 0x20, 0xcf, 0x20,
|
||||
0xd0, 0x20, 0xd1, 0x20, 0xd2, 0x20, 0xd3, 0x20,
|
||||
0xd4, 0x20, 0xd5, 0x20, 0xd6, 0x20, 0xd7, 0x20,
|
||||
0xd8, 0x20, 0xd9, 0x20, 0xda, 0x20, 0xdb, 0x20,
|
||||
0xdc, 0x20, 0xdd, 0x20, 0xde, 0x20, 0xdf, 0x20,
|
||||
0xe0, 0x20, 0xe1, 0x20, 0xe2, 0x20, 0xe3, 0x20,
|
||||
0xe4, 0x20, 0xe5, 0x20, 0xe6, 0x20, 0xe7, 0x20,
|
||||
0xe8, 0x20, 0xe9, 0x20, 0xea, 0x20, 0xeb, 0x20,
|
||||
0xec, 0x20, 0xed, 0x20, 0xee, 0x20, 0xef, 0x20,
|
||||
0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, 0x20,
|
||||
0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20,
|
||||
0xf8, 0x20, 0xf9, 0x20, 0xfa, 0x20, 0xfb, 0x20,
|
||||
0xfc, 0x20, 0xfd, 0x20, 0xfe, 0x20, 0xff, 0x20,
|
||||
0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21,
|
||||
0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21,
|
||||
0x08, 0x21, 0x09, 0x21, 0x0a, 0x21, 0x0b, 0x21,
|
||||
0x0c, 0x21, 0x0d, 0x21, 0x0e, 0x21, 0x0f, 0x21,
|
||||
0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21,
|
||||
0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21,
|
||||
0x18, 0x21, 0x19, 0x21, 0x1a, 0x21, 0x1b, 0x21,
|
||||
0x1c, 0x21, 0x1d, 0x21, 0x1e, 0x21, 0x1f, 0x21,
|
||||
0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21,
|
||||
0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21,
|
||||
0x28, 0x21, 0x29, 0x21, 0x2a, 0x21, 0x2b, 0x21,
|
||||
0x2c, 0x21, 0x2d, 0x21, 0x2e, 0x21, 0x2f, 0x21,
|
||||
0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21,
|
||||
0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21,
|
||||
0x38, 0x21, 0x39, 0x21, 0x3a, 0x21, 0x3b, 0x21,
|
||||
0x3c, 0x21, 0x3d, 0x21, 0x3e, 0x21, 0x3f, 0x21,
|
||||
0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21,
|
||||
0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21,
|
||||
0x48, 0x21, 0x49, 0x21, 0x4a, 0x21, 0x4b, 0x21,
|
||||
0x4c, 0x21, 0x4d, 0x21, 0x32, 0x21, 0x4f, 0x21,
|
||||
0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21,
|
||||
0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21,
|
||||
0x58, 0x21, 0x59, 0x21, 0x5a, 0x21, 0x5b, 0x21,
|
||||
0x5c, 0x21, 0x5d, 0x21, 0x5e, 0x21, 0x5f, 0x21,
|
||||
0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21,
|
||||
0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21,
|
||||
0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21,
|
||||
0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21,
|
||||
0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21,
|
||||
0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21,
|
||||
0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21,
|
||||
0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21,
|
||||
0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21,
|
||||
0x83, 0x21, 0xff, 0xff, 0x4b, 0x03, 0xb6, 0x24,
|
||||
0xb7, 0x24, 0xb8, 0x24, 0xb9, 0x24, 0xba, 0x24,
|
||||
0xbb, 0x24, 0xbc, 0x24, 0xbd, 0x24, 0xbe, 0x24,
|
||||
0xbf, 0x24, 0xc0, 0x24, 0xc1, 0x24, 0xc2, 0x24,
|
||||
0xc3, 0x24, 0xc4, 0x24, 0xc5, 0x24, 0xc6, 0x24,
|
||||
0xc7, 0x24, 0xc8, 0x24, 0xc9, 0x24, 0xca, 0x24,
|
||||
0xcb, 0x24, 0xcc, 0x24, 0xcd, 0x24, 0xce, 0x24,
|
||||
0xcf, 0x24, 0xff, 0xff, 0x46, 0x07, 0x00, 0x2c,
|
||||
0x01, 0x2c, 0x02, 0x2c, 0x03, 0x2c, 0x04, 0x2c,
|
||||
0x05, 0x2c, 0x06, 0x2c, 0x07, 0x2c, 0x08, 0x2c,
|
||||
0x09, 0x2c, 0x0a, 0x2c, 0x0b, 0x2c, 0x0c, 0x2c,
|
||||
0x0d, 0x2c, 0x0e, 0x2c, 0x0f, 0x2c, 0x10, 0x2c,
|
||||
0x11, 0x2c, 0x12, 0x2c, 0x13, 0x2c, 0x14, 0x2c,
|
||||
0x15, 0x2c, 0x16, 0x2c, 0x17, 0x2c, 0x18, 0x2c,
|
||||
0x19, 0x2c, 0x1a, 0x2c, 0x1b, 0x2c, 0x1c, 0x2c,
|
||||
0x1d, 0x2c, 0x1e, 0x2c, 0x1f, 0x2c, 0x20, 0x2c,
|
||||
0x21, 0x2c, 0x22, 0x2c, 0x23, 0x2c, 0x24, 0x2c,
|
||||
0x25, 0x2c, 0x26, 0x2c, 0x27, 0x2c, 0x28, 0x2c,
|
||||
0x29, 0x2c, 0x2a, 0x2c, 0x2b, 0x2c, 0x2c, 0x2c,
|
||||
0x2d, 0x2c, 0x2e, 0x2c, 0x5f, 0x2c, 0x60, 0x2c,
|
||||
0x60, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c,
|
||||
0x65, 0x2c, 0x66, 0x2c, 0x67, 0x2c, 0x67, 0x2c,
|
||||
0x69, 0x2c, 0x69, 0x2c, 0x6b, 0x2c, 0x6b, 0x2c,
|
||||
0x6d, 0x2c, 0x6e, 0x2c, 0x6f, 0x2c, 0x70, 0x2c,
|
||||
0x71, 0x2c, 0x72, 0x2c, 0x73, 0x2c, 0x74, 0x2c,
|
||||
0x75, 0x2c, 0x75, 0x2c, 0x77, 0x2c, 0x78, 0x2c,
|
||||
0x79, 0x2c, 0x7a, 0x2c, 0x7b, 0x2c, 0x7c, 0x2c,
|
||||
0x7d, 0x2c, 0x7e, 0x2c, 0x7f, 0x2c, 0x80, 0x2c,
|
||||
0x80, 0x2c, 0x82, 0x2c, 0x82, 0x2c, 0x84, 0x2c,
|
||||
0x84, 0x2c, 0x86, 0x2c, 0x86, 0x2c, 0x88, 0x2c,
|
||||
0x88, 0x2c, 0x8a, 0x2c, 0x8a, 0x2c, 0x8c, 0x2c,
|
||||
0x8c, 0x2c, 0x8e, 0x2c, 0x8e, 0x2c, 0x90, 0x2c,
|
||||
0x90, 0x2c, 0x92, 0x2c, 0x92, 0x2c, 0x94, 0x2c,
|
||||
0x94, 0x2c, 0x96, 0x2c, 0x96, 0x2c, 0x98, 0x2c,
|
||||
0x98, 0x2c, 0x9a, 0x2c, 0x9a, 0x2c, 0x9c, 0x2c,
|
||||
0x9c, 0x2c, 0x9e, 0x2c, 0x9e, 0x2c, 0xa0, 0x2c,
|
||||
0xa0, 0x2c, 0xa2, 0x2c, 0xa2, 0x2c, 0xa4, 0x2c,
|
||||
0xa4, 0x2c, 0xa6, 0x2c, 0xa6, 0x2c, 0xa8, 0x2c,
|
||||
0xa8, 0x2c, 0xaa, 0x2c, 0xaa, 0x2c, 0xac, 0x2c,
|
||||
0xac, 0x2c, 0xae, 0x2c, 0xae, 0x2c, 0xb0, 0x2c,
|
||||
0xb0, 0x2c, 0xb2, 0x2c, 0xb2, 0x2c, 0xb4, 0x2c,
|
||||
0xb4, 0x2c, 0xb6, 0x2c, 0xb6, 0x2c, 0xb8, 0x2c,
|
||||
0xb8, 0x2c, 0xba, 0x2c, 0xba, 0x2c, 0xbc, 0x2c,
|
||||
0xbc, 0x2c, 0xbe, 0x2c, 0xbe, 0x2c, 0xc0, 0x2c,
|
||||
0xc0, 0x2c, 0xc2, 0x2c, 0xc2, 0x2c, 0xc4, 0x2c,
|
||||
0xc4, 0x2c, 0xc6, 0x2c, 0xc6, 0x2c, 0xc8, 0x2c,
|
||||
0xc8, 0x2c, 0xca, 0x2c, 0xca, 0x2c, 0xcc, 0x2c,
|
||||
0xcc, 0x2c, 0xce, 0x2c, 0xce, 0x2c, 0xd0, 0x2c,
|
||||
0xd0, 0x2c, 0xd2, 0x2c, 0xd2, 0x2c, 0xd4, 0x2c,
|
||||
0xd4, 0x2c, 0xd6, 0x2c, 0xd6, 0x2c, 0xd8, 0x2c,
|
||||
0xd8, 0x2c, 0xda, 0x2c, 0xda, 0x2c, 0xdc, 0x2c,
|
||||
0xdc, 0x2c, 0xde, 0x2c, 0xde, 0x2c, 0xe0, 0x2c,
|
||||
0xe0, 0x2c, 0xe2, 0x2c, 0xe2, 0x2c, 0xe4, 0x2c,
|
||||
0xe5, 0x2c, 0xe6, 0x2c, 0xe7, 0x2c, 0xe8, 0x2c,
|
||||
0xe9, 0x2c, 0xea, 0x2c, 0xeb, 0x2c, 0xec, 0x2c,
|
||||
0xed, 0x2c, 0xee, 0x2c, 0xef, 0x2c, 0xf0, 0x2c,
|
||||
0xf1, 0x2c, 0xf2, 0x2c, 0xf3, 0x2c, 0xf4, 0x2c,
|
||||
0xf5, 0x2c, 0xf6, 0x2c, 0xf7, 0x2c, 0xf8, 0x2c,
|
||||
0xf9, 0x2c, 0xfa, 0x2c, 0xfb, 0x2c, 0xfc, 0x2c,
|
||||
0xfd, 0x2c, 0xfe, 0x2c, 0xff, 0x2c, 0xa0, 0x10,
|
||||
0xa1, 0x10, 0xa2, 0x10, 0xa3, 0x10, 0xa4, 0x10,
|
||||
0xa5, 0x10, 0xa6, 0x10, 0xa7, 0x10, 0xa8, 0x10,
|
||||
0xa9, 0x10, 0xaa, 0x10, 0xab, 0x10, 0xac, 0x10,
|
||||
0xad, 0x10, 0xae, 0x10, 0xaf, 0x10, 0xb0, 0x10,
|
||||
0xb1, 0x10, 0xb2, 0x10, 0xb3, 0x10, 0xb4, 0x10,
|
||||
0xb5, 0x10, 0xb6, 0x10, 0xb7, 0x10, 0xb8, 0x10,
|
||||
0xb9, 0x10, 0xba, 0x10, 0xbb, 0x10, 0xbc, 0x10,
|
||||
0xbd, 0x10, 0xbe, 0x10, 0xbf, 0x10, 0xc0, 0x10,
|
||||
0xc1, 0x10, 0xc2, 0x10, 0xc3, 0x10, 0xc4, 0x10,
|
||||
0xc5, 0x10, 0xff, 0xff, 0x1b, 0xd2, 0x21, 0xff,
|
||||
0x22, 0xff, 0x23, 0xff, 0x24, 0xff, 0x25, 0xff,
|
||||
0x26, 0xff, 0x27, 0xff, 0x28, 0xff, 0x29, 0xff,
|
||||
0x2a, 0xff, 0x2b, 0xff, 0x2c, 0xff, 0x2d, 0xff,
|
||||
0x2e, 0xff, 0x2f, 0xff, 0x30, 0xff, 0x31, 0xff,
|
||||
0x32, 0xff, 0x33, 0xff, 0x34, 0xff, 0x35, 0xff,
|
||||
0x36, 0xff, 0x37, 0xff, 0x38, 0xff, 0x39, 0xff,
|
||||
0x3a, 0xff, 0x5b, 0xff, 0x5c, 0xff, 0x5d, 0xff,
|
||||
0x5e, 0xff, 0x5f, 0xff, 0x60, 0xff, 0x61, 0xff,
|
||||
0x62, 0xff, 0x63, 0xff, 0x64, 0xff, 0x65, 0xff,
|
||||
0x66, 0xff, 0x67, 0xff, 0x68, 0xff, 0x69, 0xff,
|
||||
0x6a, 0xff, 0x6b, 0xff, 0x6c, 0xff, 0x6d, 0xff,
|
||||
0x6e, 0xff, 0x6f, 0xff, 0x70, 0xff, 0x71, 0xff,
|
||||
0x72, 0xff, 0x73, 0xff, 0x74, 0xff, 0x75, 0xff,
|
||||
0x76, 0xff, 0x77, 0xff, 0x78, 0xff, 0x79, 0xff,
|
||||
0x7a, 0xff, 0x7b, 0xff, 0x7c, 0xff, 0x7d, 0xff,
|
||||
0x7e, 0xff, 0x7f, 0xff, 0x80, 0xff, 0x81, 0xff,
|
||||
0x82, 0xff, 0x83, 0xff, 0x84, 0xff, 0x85, 0xff,
|
||||
0x86, 0xff, 0x87, 0xff, 0x88, 0xff, 0x89, 0xff,
|
||||
0x8a, 0xff, 0x8b, 0xff, 0x8c, 0xff, 0x8d, 0xff,
|
||||
0x8e, 0xff, 0x8f, 0xff, 0x90, 0xff, 0x91, 0xff,
|
||||
0x92, 0xff, 0x93, 0xff, 0x94, 0xff, 0x95, 0xff,
|
||||
0x96, 0xff, 0x97, 0xff, 0x98, 0xff, 0x99, 0xff,
|
||||
0x9a, 0xff, 0x9b, 0xff, 0x9c, 0xff, 0x9d, 0xff,
|
||||
0x9e, 0xff, 0x9f, 0xff, 0xa0, 0xff, 0xa1, 0xff,
|
||||
0xa2, 0xff, 0xa3, 0xff, 0xa4, 0xff, 0xa5, 0xff,
|
||||
0xa6, 0xff, 0xa7, 0xff, 0xa8, 0xff, 0xa9, 0xff,
|
||||
0xaa, 0xff, 0xab, 0xff, 0xac, 0xff, 0xad, 0xff,
|
||||
0xae, 0xff, 0xaf, 0xff, 0xb0, 0xff, 0xb1, 0xff,
|
||||
0xb2, 0xff, 0xb3, 0xff, 0xb4, 0xff, 0xb5, 0xff,
|
||||
0xb6, 0xff, 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xff,
|
||||
0xba, 0xff, 0xbb, 0xff, 0xbc, 0xff, 0xbd, 0xff,
|
||||
0xbe, 0xff, 0xbf, 0xff, 0xc0, 0xff, 0xc1, 0xff,
|
||||
0xc2, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc5, 0xff,
|
||||
0xc6, 0xff, 0xc7, 0xff, 0xc8, 0xff, 0xc9, 0xff,
|
||||
0xca, 0xff, 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0xff,
|
||||
0xce, 0xff, 0xcf, 0xff, 0xd0, 0xff, 0xd1, 0xff,
|
||||
0xd2, 0xff, 0xd3, 0xff, 0xd4, 0xff, 0xd5, 0xff,
|
||||
0xd6, 0xff, 0xd7, 0xff, 0xd8, 0xff, 0xd9, 0xff,
|
||||
0xda, 0xff, 0xdb, 0xff, 0xdc, 0xff, 0xdd, 0xff,
|
||||
0xde, 0xff, 0xdf, 0xff, 0xe0, 0xff, 0xe1, 0xff,
|
||||
0xe2, 0xff, 0xe3, 0xff, 0xe4, 0xff, 0xe5, 0xff,
|
||||
0xe6, 0xff, 0xe7, 0xff, 0xe8, 0xff, 0xe9, 0xff,
|
||||
0xea, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xed, 0xff,
|
||||
0xee, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf1, 0xff,
|
||||
0xf2, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf5, 0xff,
|
||||
0xf6, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf9, 0xff,
|
||||
0xfa, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfd, 0xff,
|
||||
0xfe, 0xff, 0xff, 0xff
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
uctc.h (30.10.10)
|
||||
Upper Case Table declaration.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_UCTC_H_INCLUDED
|
||||
#define MKFS_UCTC_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint8_t upcase_table[5836];
|
||||
|
||||
#endif /* ifndef MKFS_UCTC_H_INCLUDED */
|
148
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c
Normal file
148
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
vbr.c (09.11.10)
|
||||
Volume Boot Record creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "vbr.h"
|
||||
#include "fat.h"
|
||||
#include "cbm.h"
|
||||
#include "uct.h"
|
||||
#include "rootdir.h"
|
||||
#include <string.h>
|
||||
|
||||
static off_t vbr_alignment(void)
|
||||
{
|
||||
return get_sector_size();
|
||||
}
|
||||
|
||||
static off_t vbr_size(void)
|
||||
{
|
||||
return 12 * get_sector_size();
|
||||
}
|
||||
|
||||
static void init_sb(struct exfat_super_block* sb)
|
||||
{
|
||||
uint32_t clusters_max;
|
||||
uint32_t fat_sectors;
|
||||
|
||||
clusters_max = get_volume_size() / get_cluster_size();
|
||||
fat_sectors = DIV_ROUND_UP((off_t) clusters_max * sizeof(cluster_t),
|
||||
get_sector_size());
|
||||
|
||||
memset(sb, 0, sizeof(struct exfat_super_block));
|
||||
sb->jump[0] = 0xeb;
|
||||
sb->jump[1] = 0x76;
|
||||
sb->jump[2] = 0x90;
|
||||
memcpy(sb->oem_name, "EXFAT ", sizeof(sb->oem_name));
|
||||
sb->sector_start = cpu_to_le64(get_first_sector());
|
||||
sb->sector_count = cpu_to_le64(get_volume_size() / get_sector_size());
|
||||
sb->fat_sector_start = cpu_to_le32(
|
||||
fat.get_alignment() / get_sector_size());
|
||||
sb->fat_sector_count = cpu_to_le32(ROUND_UP(
|
||||
le32_to_cpu(sb->fat_sector_start) + fat_sectors,
|
||||
1 << get_spc_bits()) -
|
||||
le32_to_cpu(sb->fat_sector_start));
|
||||
sb->cluster_sector_start = cpu_to_le32(
|
||||
get_position(&cbm) / get_sector_size());
|
||||
sb->cluster_count = cpu_to_le32(clusters_max -
|
||||
((le32_to_cpu(sb->fat_sector_start) +
|
||||
le32_to_cpu(sb->fat_sector_count)) >> get_spc_bits()));
|
||||
sb->rootdir_cluster = cpu_to_le32(
|
||||
(get_position(&rootdir) - get_position(&cbm)) / get_cluster_size()
|
||||
+ EXFAT_FIRST_DATA_CLUSTER);
|
||||
sb->volume_serial = cpu_to_le32(get_volume_serial());
|
||||
sb->version.major = 1;
|
||||
sb->version.minor = 0;
|
||||
sb->volume_state = cpu_to_le16(0);
|
||||
sb->sector_bits = get_sector_bits();
|
||||
sb->spc_bits = get_spc_bits();
|
||||
sb->fat_count = 1;
|
||||
sb->drive_no = 0x80;
|
||||
sb->allocated_percent = 0;
|
||||
sb->boot_signature = cpu_to_le16(0xaa55);
|
||||
}
|
||||
|
||||
static int vbr_write(struct exfat_dev* dev)
|
||||
{
|
||||
struct exfat_super_block sb;
|
||||
uint32_t checksum;
|
||||
le32_t* sector = malloc(get_sector_size());
|
||||
size_t i;
|
||||
|
||||
if (sector == NULL)
|
||||
{
|
||||
exfat_error("failed to allocate sector-sized block of memory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
init_sb(&sb);
|
||||
if (exfat_write(dev, &sb, sizeof(struct exfat_super_block)) < 0)
|
||||
{
|
||||
free(sector);
|
||||
exfat_error("failed to write super block sector");
|
||||
return 1;
|
||||
}
|
||||
checksum = exfat_vbr_start_checksum(&sb, sizeof(struct exfat_super_block));
|
||||
|
||||
memset(sector, 0, get_sector_size());
|
||||
sector[get_sector_size() / sizeof(sector[0]) - 1] =
|
||||
cpu_to_le32(0xaa550000);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (exfat_write(dev, sector, get_sector_size()) < 0)
|
||||
{
|
||||
free(sector);
|
||||
exfat_error("failed to write a sector with boot signature");
|
||||
return 1;
|
||||
}
|
||||
checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum);
|
||||
}
|
||||
|
||||
memset(sector, 0, get_sector_size());
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (exfat_write(dev, sector, get_sector_size()) < 0)
|
||||
{
|
||||
free(sector);
|
||||
exfat_error("failed to write an empty sector");
|
||||
return 1;
|
||||
}
|
||||
checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum);
|
||||
}
|
||||
|
||||
for (i = 0; i < get_sector_size() / sizeof(sector[0]); i++)
|
||||
sector[i] = cpu_to_le32(checksum);
|
||||
if (exfat_write(dev, sector, get_sector_size()) < 0)
|
||||
{
|
||||
free(sector);
|
||||
exfat_error("failed to write checksum sector");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(sector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fs_object vbr =
|
||||
{
|
||||
.get_alignment = vbr_alignment,
|
||||
.get_size = vbr_size,
|
||||
.write = vbr_write,
|
||||
};
|
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h
Normal file
30
LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
vbr.h (09.11.10)
|
||||
Volume Boot Record creation code.
|
||||
|
||||
Free exFAT implementation.
|
||||
Copyright (C) 2011-2018 Andrew Nayenko
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MKFS_VBR_H_INCLUDED
|
||||
#define MKFS_VBR_H_INCLUDED
|
||||
|
||||
#include "mkexfat.h"
|
||||
|
||||
extern const struct fs_object vbr;
|
||||
|
||||
#endif /* ifndef MKFS_VBR_H_INCLUDED */
|
Loading…
Add table
Add a link
Reference in a new issue