exfatprogs 升级到1.3.2

Signed-off-by: jiangqianrong <jiangqianrong1@huawei.com>
This commit is contained in:
jiangqianrong
2026-04-10 17:34:05 +08:00
parent 58cf4928f7
commit 74df28d5dc
43 changed files with 3862 additions and 820 deletions
+5 -8
View File
@@ -19,10 +19,11 @@ jobs:
- uses: actions/checkout@v4
- name: before test
run: |
sudo apt-get install linux-headers-$(uname -r) xz-utils \
gcc-mips-linux-gnu qemu-system-mips \
qemu-user
git clone https://github.com/namjaejeon/linux-exfat-oot
sudo apt-get --update --quiet --yes install \
linux-headers-$(uname -r) xz-utils \
gcc-mips-linux-gnu qemu-system-mips \
qemu-user
sudo apt-get install -y linux-modules-extra-$(uname -r)
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/lib:$PATH
- name: build test & install exfatprogs
@@ -45,12 +46,8 @@ jobs:
sudo -E ./test_fsck.sh
- name: create file/director test
run: |
cd linux-exfat-oot
make > /dev/null
sudo make install > /dev/null
sudo modprobe exfat
sudo mkdir -p /mnt/test
cd ..
truncate -s 10G test.img
sudo losetup /dev/loop22 test.img
sudo mkfs.exfat /dev/loop22
+3 -2
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Copyright (c) 2026 Huawei Device Co., Ltd.
#
# 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
@@ -30,7 +30,7 @@ config("exfat-defaults") {
"-Wno-error",
"-D_FILE_OFFSET_BITS=64",
"-DPACKAGE=\"exfatprogs\"",
"-DVERSION=\"1.2.5\"",
"-DVERSION=\"1.3.2\"",
]
include_dirs = [
"dump",
@@ -88,6 +88,7 @@ ohos_executable("fsck.exfat") {
sources = [
"fsck/fsck.c",
"fsck/repair.c",
"lib/utils.c",
]
include_dirs = [
+110
View File
@@ -1,3 +1,113 @@
exfatprogs 1.3.2 - release 2026-03-09
===================================
NEW FEATURES :
* fsck.exfat: add an option to show a progress bar
while checking a filesystem.
CHANGES :
* mkfs.exfat: discard blocks prior to write outs by
default.
* mkfs.exfat: add a read-after-write verification for
the volume boot record.
* exfatprogs: adjust utility exit codes and add log
messages for malloc() failures.
BUG FIXES :
* dump.exfat: handle paths including '.', '..', and
repeated '/'.
* fsck.exfat: convert 0x80 entries into deleted file
entries to avoid bogus dentry errors.
* fsck.exfat: fix an uninitialized variable warning.
exfatprogs 1.3.1 - released 2025-12-15
=====================================
NEW FEATURES :
* fsck.exfat: support repairing the allocation bitmap size.
CHANGES :
* exfatprogs: temporarily disable building defrag.exfat due to reported
data loss.
BUG FIXES :
* libexfat: fix a NULL pointer dereference in read_file_dentry_set().
exfatprogs 1.3.0 - released 2025-10-15
======================================
NEW FEATURES :
* defrag.exfat: add a tool to defragment an exFAT
filesystem or assess its fragmentation status.
See a man page.
CHANGES :
* mkfs.exfat: minimize zero-out initialization work
in quick format mode to reduce I/O time.
* fsck.exfat: set the entry after an unused entry as unused.
BUG FIXES :
* mkfs.exfat: fix incorrect FAT byte length calculation.
* mkfs.exfat: avoid setting physical sector size into sector_size field.
* fsck.exfat: fix a memory leaks in an error path.
exfatprogs 1.2.9 - released 2025-05-12
======================================
NEW FEATURES :
* dump.exfat: support dumping directory entry sets,
which prints all fields of directory entries and
cluster chains. See a man page.
CHANGES :
* exfatprogs: update the Github action for build test
with Debain + clang + lld.
exfatprogs 1.2.8 - released 2025-03-04
======================================
BUG FIXES :
* dump.exfat: fix an incorrect output of an entry
position in 32-bit system.
* mkfs.exfat: fill an oem sector with zero instead
of one.
* exfatprogs: fix compilation on musl based systems
due to loff_t type. And update the Github action
to validate builds on the system.
exfatprogs 1.2.7 - released 2025-02-03
======================================
NEW FEATURES :
* fsck.exfat: support repairing the upcase table.
CHANGES :
* exfatprogs: make sure to load the tbl preprocessor
for man pages.
BUG FIXES :
* exfatprogs: fix a double free memory error.
* dump.exfat: fix a constraint that volume label, bitmap,
upcase table must be located at the beginning of a root
directory.
exfatprogs 1.2.6 - released 2024-11-20
======================================
CHANGES :
* exfatprogs: replace obsolete autoconf and libtool
macros.
* mkfs.exfat: prefer the physical block size over
the logical block size for the exFAT sector size.
* mkfs.exfat: add notes about the format of the volume
GUID to the man page.
* mkfs.exfat: fix an incorrect calculation of the number
of used clusters.
BUG FIXES :
* exfatlabel: fix an user input error when setting
a volume serial or label.
exfatprogs 1.2.5 - released 2024-08-06
======================================
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2022 Huawei Device Co., Ltd.
<!-- Copyright (c) 2026 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+2 -2
View File
@@ -3,9 +3,9 @@
"Name" : "exfatprogs",
"License" : "GPL-2.0-or-later",
"License File" : "COPYING",
"Version Number" : "1.2.5",
"Version Number" : "1.3.2",
"Owner" : "Namjae Jeon",
"Upstream URL" : "https://github.com/exfatprogs/exfatprogs/archive/refs/tags/1.2.5.tar.gz",
"Upstream URL" : "https://github.com/exfatprogs/exfatprogs/archive/refs/tags/1.3.2.tar.gz",
"Description" : "exFAT filesystem userspace utilities."
}
]
+3 -4
View File
@@ -1,4 +1,4 @@
AC_PREREQ([2.68])
AC_PREREQ([2.70])
m4_define([exfat_progs_version], m4_esyscmd_s(
grep "define EXFAT_PROGS_VERSION " include/version.h | \
@@ -11,16 +11,15 @@ AC_INIT([exfatprogs],
[https://github.com/exfatprogs/exfatprogs])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign tar-pax dist-xz subdir-objects])
AC_LANG([C])
AC_PROG_CC
AC_PROG_CC_STDC
AM_SILENT_RULES([yes])
AC_PROG_LIBTOOL
LT_INIT
AC_SYS_LARGEFILE
AC_C_BIGENDIAN
+6
View File
@@ -0,0 +1,6 @@
AM_CFLAGS = -Wall -Wextra -include $(top_builddir)/config.h -I$(top_srcdir)/include -fno-common
defrag_exfat_LDADD = $(top_builddir)/lib/libexfat.a
sbin_PROGRAMS = defrag.exfat
defrag_exfat_SOURCES = defrag.c defrag.h
+1164
View File
File diff suppressed because it is too large Load Diff
+61
View File
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2025 Haodong Xia <3394797836@qq.com>
*/
#ifndef _DEFRAG_H
#define _DEFRAG_H
#include <stdint.h>
struct exfat;
struct buffer_desc;
/*
* This structure tracks the linkage of all cluster chains on the device.
*
* In exFAT, a cluster chain is typically represented by:
* - The 'first cluster' field in directory entries (e.g., file/directory start)
* - The rest of the chain maintained by FAT entries
*
* We model this as a linked list with two types of nodes:
* - Virtual Node: Represents the 'first cluster' from directory entries
* - Physical Node: Represents clusters linked by FAT entries
*
* Each chain starts with a Virtual Node, followed by zero or more Physical Nodes.
* The entire structure is maintained as a doubly-linked list using two arrays:
* - 'next_clus': stores forward pointers
* - 'prev_clus': stores backward pointers
*
* Virtual Nodes are placed after Physical Nodes in the arrays.
* Since the number of Virtual Nodes (i.e., number of files/directories)
* is unknown until the file tree is traversed, memory for them is allocated dynamically.
*/
struct cluster_info_set {
uint32_t *next_clus; /* Forward pointers for the doubly-linked list */
uint32_t *prev_clus; /* Backward pointers for the doubly-linked list */
uint32_t num_phys_clus; /* Number of physical clusters (Physical Nodes) */
uint32_t num_clus_chain; /*
* Number of cluster chains (Virtual Nodes),
* one per file/directory
*/
};
#define VIRT_SPACE_ALIGN 4096 /* Allocate virtual nodes in chunks of 4096 */
/* Core metadata for defragmentation */
struct exfat_defrag {
struct exfat *exfat; /* File system metadata */
struct cluster_info_set clu_info_set; /*
* Doubly-linked list representing cluster
* chain structure
*/
struct buffer_desc *dentry_buffer; /* Temporary storage for directory entries */
uint8_t *tmp_clus; /* Temporary buffer for cluster swapping */
};
/* Reference for fragmentation assessment */
#define WATERMARK_1 30
#define WATERMARK_2 70
#endif
+826 -94
View File
File diff suppressed because it is too large Load Diff
+8 -21
View File
@@ -108,13 +108,11 @@ static void free_exfat2img(struct exfat2img *ei)
close(ei->bdev.dev_fd);
}
static int create_exfat2img(struct exfat2img *ei,
struct pbr *bs,
const char *out_path)
static int create_exfat2img(struct exfat2img *ei, const char *out_path)
{
int err;
ei->exfat = exfat_alloc_exfat(&ei->bdev, bs);
ei->exfat = exfat_alloc_exfat(&ei->bdev, NULL, NULL);
if (!ei->exfat)
return -ENOMEM;
@@ -273,18 +271,14 @@ static int dump_directory(struct exfat2img *ei,
static int dump_root(struct exfat2img *ei)
{
struct exfat *exfat = ei->exfat;
struct exfat_inode *root;
clus_t clus_count = 0;
root = exfat_alloc_inode(ATTR_SUBDIR);
if (!root)
return -ENOMEM;
dump_directory(ei, exfat->root, (size_t)-1, &clus_count);
if (exfat->root->size != clus_count * exfat->clus_size) {
exfat_debug("the root dir is corrupted\n");
return -EINVAL;
}
root->first_clus = le32_to_cpu(exfat->bs->bsx.root_cluster);
dump_directory(ei, root, (size_t)-1, &clus_count);
root->size = clus_count * exfat->clus_size;
ei->exfat->root = root;
return 0;
}
@@ -884,7 +878,6 @@ int main(int argc, char * const argv[])
{
int err = 0, c;
const char *in_path, *out_path = NULL, *blkdev_path;
struct pbr *bs;
struct exfat_user_input ui;
off_t last_sect;
bool restore;
@@ -940,13 +933,7 @@ int main(int argc, char * const argv[])
if (restore)
return restore_from_stdin(&ei);
err = read_boot_sect(&ei.bdev, &bs);
if (err) {
close(ei.bdev.dev_fd);
return EXIT_FAILURE;
}
err = create_exfat2img(&ei, bs, out_path);
err = create_exfat2img(&ei, out_path);
if (err)
return EXIT_FAILURE;
+288 -41
View File
@@ -19,6 +19,7 @@
#include "exfat_fs.h"
#include "exfat_dir.h"
#include "fsck.h"
#include "upcase_table.h"
struct fsck_user_input {
struct exfat_user_input ei;
@@ -58,6 +59,7 @@ static struct option opts[] = {
{"help", no_argument, NULL, 'h' },
{"?", no_argument, NULL, '?' },
{"ignore-bad-fs", no_argument, NULL, 'b' },
{"progress", no_argument, NULL, 'P' },
{NULL, 0, NULL, 0 }
};
@@ -71,6 +73,7 @@ static void usage(char *name)
fprintf(stderr, "\t-a Repair automatically\n");
fprintf(stderr, "\t-b | --ignore-bad-fs Try to recover even if exfat is not found\n");
fprintf(stderr, "\t-s | --rescue Assign orphaned clusters to files\n");
fprintf(stderr, "\t-P | --progress Show progress bar\n");
fprintf(stderr, "\t-V | --version Show version\n");
fprintf(stderr, "\t-v | --verbose Print debug\n");
fprintf(stderr, "\t-h | --help Show help\n");
@@ -166,6 +169,8 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, int stream_idx,
clus))
return -EINVAL;
}
if (exfat_fsck.options & FSCK_OPTS_PROGRESS_BAR)
progress_update(&exfat_fsck.progress_bar, 1);
/* This cluster is allocated or not */
if (exfat_get_inode_next_clus(exfat, node, clus, &next))
@@ -244,14 +249,12 @@ static int root_check_clus_chain(struct exfat *exfat,
struct exfat_inode *node,
clus_t *clus_count)
{
clus_t clus, next, prev = EXFAT_EOF_CLUSTER;
clus_t clus = node->first_clus, next, prev = EXFAT_EOF_CLUSTER;
*clus_count = 0;
if (!exfat_heap_clus(exfat, node->first_clus))
goto out_trunc;
clus = node->first_clus;
*clus_count = 0;
do {
if (exfat_bitmap_get(exfat->alloc_bitmap, clus)) {
if (exfat_repair_ask(&exfat_fsck,
@@ -935,7 +938,7 @@ skip_dset:
break;
if (need_delete) {
exfat_de_iter_get_dirty(iter, i, &dentry);
dentry->type &= EXFAT_DELETE;
dentry->type = EXFAT_DELETE;
}
}
*skip_dentries = i;
@@ -979,6 +982,7 @@ static int read_bitmap(struct exfat *exfat)
.in.param = NULL,
};
struct exfat_dentry *dentry;
uint64_t map_size, need_map_size;
int retval;
retval = exfat_lookup_dentry_set(exfat, exfat->root, &filter);
@@ -990,6 +994,20 @@ static int read_bitmap(struct exfat *exfat)
le32_to_cpu(dentry->bitmap_start_clu),
le64_to_cpu(dentry->bitmap_size));
/* Validate on-disk bitmap size and required size */
map_size = le64_to_cpu(dentry->bitmap_size);
need_map_size = DIV_ROUND_UP(exfat->clus_count, 8);
if (map_size != need_map_size &&
exfat_repair_ask(&exfat_fsck, ER_DE_BITMAP,
"ERROR: invalid bitmap size. %lld", map_size)) {
dentry->bitmap_size = cpu_to_le64(need_map_size);
if (pwrite(exfat->blk_dev->dev_fd, dentry, DENTRY_SIZE,
filter.out.dev_offset) != DENTRY_SIZE) {
exfat_err("failed to write bitmap dentry\n");
return -EIO;
}
}
if (le64_to_cpu(dentry->bitmap_size) <
DIV_ROUND_UP(exfat->clus_count, 8)) {
exfat_err("invalid size of allocation bitmap. 0x%" PRIx64 "\n",
@@ -1046,40 +1064,172 @@ static int decompress_upcase_table(const __le16 *in_table, size_t in_len,
return 0;
}
static int read_upcase_table(struct exfat *exfat)
static bool exfat_has_default_upcase_table(struct exfat *exfat, clus_t *clu)
{
char *upcase;
bool ret = false;
int size;
clus_t def_clu = DIV_ROUND_UP(EXFAT_BITMAP_SIZE(exfat->clus_count),
exfat->clus_size) + EXFAT_FIRST_CLUSTER;
upcase = malloc(sizeof(default_upcase_table));
if (!upcase)
return false;
if (!exfat_heap_clus(exfat, *clu))
*clu = def_clu;
again:
size = pread(exfat->blk_dev->dev_fd, upcase,
sizeof(default_upcase_table),
exfat_c2o(exfat, *clu));
if (size == sizeof(default_upcase_table)) {
if (!memcmp(upcase, default_upcase_table, size)) {
ret = true;
goto out;
}
if (*clu != def_clu) {
*clu = def_clu;
goto again;
}
}
out:
free(upcase);
return ret;
}
static int exfat_repair_upcase_table(struct exfat *exfat,
struct exfat_dentry *dentry, off_t dentry_off)
{
clus_t clu;
int ret;
off_t upcase_off;
size_t nbytes;
struct exfat_dentry ed;
int fd = exfat->blk_dev->dev_fd;
unsigned int clu_count = DIV_ROUND_UP(sizeof(default_upcase_table),
exfat->clus_size);
/* Allocate a new cluster if root dir has not empty dentry */
if (dentry_off == EOF) {
if (exfat_alloc_cluster(exfat, exfat->root, &clu)) {
exfat_err("No space to store upcase_table entry\n");
return -ENOSPC;
}
dentry_off = exfat_c2o(exfat, clu);
}
clu = EXFAT_EOF_CLUSTER;
if (dentry == NULL)
dentry = &ed;
else if (dentry->type == EXFAT_UPCASE)
clu = le32_to_cpu(dentry->upcase_start_clu);
/*
* Write default upcase table if the upcase table entry is corrupted
* or not found the default upcase table
*/
if (!exfat_has_default_upcase_table(exfat, &clu)) {
if (exfat_find_free_cluster(exfat, clu_count, &clu)) {
exfat_err("No space to store upcase_table\n");
return -ENOSPC;
}
upcase_off = exfat_c2o(exfat, clu);
ret = pwrite(fd, default_upcase_table,
sizeof(default_upcase_table), upcase_off);
if (ret != sizeof(default_upcase_table)) {
exfat_err("failed to write new upcase_table\n");
return -EIO;
}
/* Zero the remaining space */
upcase_off += EXFAT_UPCASE_TABLE_SIZE;
nbytes = clu_count * exfat->clus_size - EXFAT_UPCASE_TABLE_SIZE;
if (nbytes) {
if (exfat_write_zero(fd, nbytes, upcase_off)) {
exfat_err("failed to zero the remaining space\n");
return -EIO;
}
}
}
/* Allocate the clusters */
exfat_bitmap_set_range(exfat, exfat->alloc_bitmap, clu, clu_count);
/* Create upcase table dentry */
memset(dentry, 0, sizeof(*dentry));
dentry->type = EXFAT_UPCASE;
dentry->upcase_start_clu = cpu_to_le32(clu);
dentry->upcase_checksum = cpu_to_le32(0xe619d30d);
dentry->upcase_size = cpu_to_le64(sizeof(default_upcase_table));
/* Write upcase table dentry */
if (pwrite(fd, dentry, DENTRY_SIZE, dentry_off) != DENTRY_SIZE) {
exfat_err("failed to write upcase_table dentry\n");
return -EIO;
}
return 0;
}
static int read_upcase_table(struct exfat_fsck *fsck)
{
struct exfat_lookup_filter filter = {
.in.type = EXFAT_UPCASE,
.in.dentry_count = 0,
.in.dentry_count = 1,
.in.filter = NULL,
.in.param = NULL,
};
struct exfat *exfat = fsck->exfat;
struct exfat_dentry *dentry = NULL;
__le16 *upcase = NULL;
__le16 *valid_upcase = (__le16 *)default_upcase_table;
ssize_t valid_upcase_size = sizeof(default_upcase_table);
int retval;
ssize_t size;
__le32 checksum;
clus_t start_clu;
off_t dentry_off;
retval = exfat_lookup_dentry_set(exfat, exfat->root, &filter);
if (retval)
if (retval == EOF) {
dentry_off = filter.out.dev_offset;
if (exfat_repair_ask(fsck, ER_DE_UPCASE,
"ERROR: not found upcase table entry"))
goto repair_upcase;
retval = -EINVAL;
goto use_default;
} else if (retval)
return retval;
dentry = filter.out.dentry_set;
start_clu = le32_to_cpu(dentry->upcase_start_clu);
dentry_off = filter.out.dev_offset;
if (!exfat_heap_clus(exfat, start_clu)) {
if (exfat_repair_ask(fsck, ER_DE_UPCASE,
"ERROR: invalid start cluster of upcase table. 0x%x", start_clu))
goto repair_upcase;
if (!exfat_heap_clus(exfat, le32_to_cpu(dentry->upcase_start_clu))) {
exfat_err("invalid start cluster of upcase table. 0x%x\n",
le32_to_cpu(dentry->upcase_start_clu));
retval = -EINVAL;
goto out;
goto use_default;
}
size = (ssize_t)le64_to_cpu(dentry->upcase_size);
if (size > (ssize_t)(EXFAT_MAX_UPCASE_CHARS * sizeof(__le16)) ||
size == 0 || size % sizeof(__le16)) {
exfat_err("invalid size of upcase table. 0x%" PRIx64 "\n",
le64_to_cpu(dentry->upcase_size));
if (exfat_repair_ask(fsck, ER_DE_UPCASE,
"ERROR: invalid size of upcase table. 0x%" PRIx64, size))
goto repair_upcase;
retval = -EINVAL;
goto out;
goto use_default;
}
upcase = malloc(size);
@@ -1100,10 +1250,13 @@ static int read_upcase_table(struct exfat *exfat)
checksum = 0;
boot_calc_checksum((unsigned char *)upcase, size, false, &checksum);
if (le32_to_cpu(dentry->upcase_checksum) != checksum) {
exfat_err("corrupted upcase table %#x (expected: %#x)\n",
checksum, le32_to_cpu(dentry->upcase_checksum));
if (exfat_repair_ask(fsck, ER_DE_UPCASE,
"ERROR: corrupted upcase table %#x (expected: %#x)",
checksum, le32_to_cpu(dentry->upcase_checksum)))
goto repair_upcase;
retval = -EINVAL;
goto out;
goto use_default;
}
exfat_bitmap_set_range(exfat, exfat->alloc_bitmap,
@@ -1111,13 +1264,27 @@ static int read_upcase_table(struct exfat *exfat)
DIV_ROUND_UP(le64_to_cpu(dentry->upcase_size),
exfat->clus_size));
valid_upcase = upcase;
valid_upcase_size = size;
repair_upcase:
if (valid_upcase != upcase)
retval = exfat_repair_upcase_table(exfat, dentry, dentry_off);
use_default:
if (valid_upcase != upcase) {
exfat_stat.error_count++;
if (retval == 0)
exfat_stat.fixed_count++;
}
exfat->upcase_table = calloc(EXFAT_UPCASE_TABLE_CHARS, sizeof(uint16_t));
if (!exfat->upcase_table) {
retval = -EIO;
goto out;
}
decompress_upcase_table(upcase, size / 2,
decompress_upcase_table(valid_upcase, valid_upcase_size / 2,
exfat->upcase_table, EXFAT_UPCASE_TABLE_CHARS);
out:
if (dentry)
@@ -1127,6 +1294,57 @@ out:
return retval;
}
/*
* Checks whether there are other directory entries following the unused
* directory entries. If so, sets the unused directory entries to the deleted
* directory entries(Type 0x7F).
*/
static int check_unused_dentry(struct exfat_de_iter *de_iter,
struct exfat_inode *dir)
{
int ret, i;
struct exfat_dentry *dentry;
int num_unused = 1;
while (1) {
exfat_de_iter_advance(de_iter, 1);
ret = exfat_de_iter_get(de_iter, 0, &dentry);
if (ret == EOF)
return 0;
else if (ret) {
fsck_err(dir->parent, dir,
"failed to get a dentry. %d\n", ret);
return ret;
}
if (dentry->type != EXFAT_LAST)
break;
num_unused++;
}
if (!repair_file_ask(de_iter, NULL, ER_DE_UNUSED,
"other entry(type: 0x%02X) follows unused entry",
dentry->type))
return -EINVAL;
ret = exfat_de_iter_revert(de_iter, num_unused);
if (ret < 0) {
fsck_err(dir->parent, dir,
"failed to revert %d dentries. %d\n", num_unused, ret);
return ret;
}
for (i = 0; i < num_unused; i++) {
exfat_de_iter_get_dirty(de_iter, 0, &dentry);
dentry->type = EXFAT_DELETE;
if (i != num_unused - 1)
exfat_de_iter_advance(de_iter, 1);
}
return 1;
}
static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir)
{
struct exfat *exfat = fsck->exfat;
@@ -1183,6 +1401,15 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir)
}
break;
case EXFAT_LAST:
ret = check_unused_dentry(de_iter, dir);
if (ret < 0) {
exfat_stat.error_count++;
break;
} else if (ret) {
exfat_stat.error_count++;
exfat_stat.fixed_count++;
break;
}
goto out;
case EXFAT_VOLUME:
case EXFAT_BITMAP:
@@ -1199,7 +1426,7 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir)
struct exfat_dentry *dentry;
exfat_de_iter_get_dirty(de_iter, 0, &dentry);
dentry->type &= EXFAT_DELETE;
dentry->type = EXFAT_DELETE;
}
break;
}
@@ -1313,22 +1540,16 @@ out:
return ret;
}
static int exfat_root_dir_check(struct exfat *exfat)
static int exfat_root_dir_check(struct exfat_fsck *fsck)
{
struct exfat_inode *root;
struct exfat *exfat = fsck->exfat;
struct exfat_inode *root = exfat->root;
clus_t clus_count = 0;
int err;
root = exfat_alloc_inode(ATTR_SUBDIR);
if (!root)
return -ENOMEM;
exfat->root = root;
root->first_clus = le32_to_cpu(exfat->bs->bsx.root_cluster);
if (root_check_clus_chain(exfat, root, &clus_count)) {
exfat_err("failed to follow the cluster chain of root\n");
exfat_free_inode(root);
exfat->root = NULL;
return -EINVAL;
}
root->size = clus_count * exfat->clus_size;
@@ -1347,20 +1568,17 @@ static int exfat_root_dir_check(struct exfat *exfat)
return -EINVAL;
}
err = read_upcase_table(exfat);
if (err) {
err = read_upcase_table(fsck);
if (err == -EINVAL)
exfat_err("upcase table is invalid, use default\n");
else if (err) {
exfat_err("failed to read upcase table\n");
return -EINVAL;
}
root->dev_offset = 0;
err = exfat_build_file_dentry_set(exfat, " ", ATTR_SUBDIR,
return exfat_build_file_dentry_set(exfat, " ", ATTR_SUBDIR,
&root->dentry_set, &root->dentry_count);
if (err) {
exfat_free_inode(root);
return -ENOMEM;
}
return 0;
}
static int read_lostfound(struct exfat *exfat, struct exfat_inode **lostfound)
@@ -1540,13 +1758,27 @@ static void exfat_show_info(struct exfat_fsck *fsck, const char *dev_name)
exfat_stat.fixed_count);
}
static clus_t count_bitmap_set_bits(struct exfat *exfat)
{
clus_t count = 0;
size_t i, bytes = exfat->disk_bitmap_size;
for (i = 0; i + sizeof(uint32_t) <= bytes; i += sizeof(uint32_t))
count += __builtin_popcount(*(uint32_t *)(exfat->disk_bitmap + i));
for (; i < bytes; i++)
count += __builtin_popcount(exfat->disk_bitmap[i]);
return count;
}
int main(int argc, char * const argv[])
{
struct fsck_user_input ui;
struct exfat_blk_dev bd;
struct pbr *bs = NULL;
struct exfat_inode *root;
int c, ret, exit_code;
bool version_only = false;
clus_t used_clus_count;
memset(&ui, 0, sizeof(ui));
memset(&bd, 0, sizeof(bd));
@@ -1557,7 +1789,7 @@ int main(int argc, char * const argv[])
exfat_err("failed to init locale/codeset\n");
opterr = 0;
while ((c = getopt_long(argc, argv, "arynpbsVvh", opts, NULL)) != EOF) {
while ((c = getopt_long(argc, argv, "arynpbsPVvh", opts, NULL)) != EOF) {
switch (c) {
case 'n':
if (ui.options & FSCK_OPTS_REPAIR_ALL)
@@ -1586,6 +1818,9 @@ int main(int argc, char * const argv[])
case 's':
ui.options |= FSCK_OPTS_RESCUE_CLUS;
break;
case 'P':
ui.options |= FSCK_OPTS_PROGRESS_BAR;
break;
case 'V':
version_only = true;
break;
@@ -1601,7 +1836,8 @@ int main(int argc, char * const argv[])
}
show_version();
if (optind != argc - 1)
if (optind != argc - 1 ||
(ui.options & FSCK_OPTS_REPAIR_ASK && ui.options & FSCK_OPTS_PROGRESS_BAR))
usage(argv[0]);
if (version_only)
@@ -1631,7 +1867,13 @@ int main(int argc, char * const argv[])
if (ret)
goto err;
exfat_fsck.exfat = exfat_alloc_exfat(&bd, bs);
root = exfat_alloc_inode(ATTR_SUBDIR);
if (!root) {
ret = -ENOMEM;
goto err;
}
exfat_fsck.exfat = exfat_alloc_exfat(&bd, bs, root);
if (!exfat_fsck.exfat) {
ret = -ENOMEM;
goto err;
@@ -1650,12 +1892,17 @@ int main(int argc, char * const argv[])
}
exfat_debug("verifying root directory...\n");
ret = exfat_root_dir_check(exfat_fsck.exfat);
ret = exfat_root_dir_check(&exfat_fsck);
if (ret) {
exfat_err("failed to verify root directory.\n");
goto out;
}
if (exfat_fsck.options & FSCK_OPTS_PROGRESS_BAR) {
used_clus_count = count_bitmap_set_bits(exfat_fsck.exfat);
progress_init(&exfat_fsck.progress_bar, 0, used_clus_count, 0);
}
exfat_debug("verifying directory entries...\n");
ret = exfat_filesystem_check(&exfat_fsck);
if (ret)
+3
View File
@@ -6,6 +6,7 @@
#define _FSCK_H
#include "list.h"
#include "utils.h"
enum fsck_ui_options {
FSCK_OPTS_REPAIR_ASK = 0x01,
@@ -16,6 +17,7 @@ enum fsck_ui_options {
FSCK_OPTS_REPAIR_ALL = 0x0f,
FSCK_OPTS_IGNORE_BAD_FS_NAME = 0x10,
FSCK_OPTS_RESCUE_CLUS = 0x20,
FSCK_OPTS_PROGRESS_BAR = 0x40,
};
struct exfat;
@@ -30,6 +32,7 @@ struct exfat_fsck {
bool dirty_fat:1;
char *name_hash_bitmap;
struct progress_bar progress_bar;
};
off_t exfat_c2o(struct exfat *exfat, unsigned int clus);
+3
View File
@@ -47,7 +47,10 @@ static struct exfat_repair_problem problems[] = {
{ER_BS_BOOT_REGION, 0, ERP_FIX, 0, 0, 0},
{ER_DE_CHECKSUM, ERF_PREEN_YES, ERP_DELETE, 0, 0, 0},
{ER_DE_UNKNOWN, ERF_PREEN_YES, ERP_DELETE, 0, 0, 0},
{ER_DE_UNUSED, ERF_PREEN_YES, ERP_FIX, 0, 0, 0},
{ER_DE_FILE, ERF_PREEN_YES, ERP_DELETE, 0, 0, 0},
{ER_DE_UPCASE, ERF_PREEN_YES, ERP_FIX, 0, 0, 0},
{ER_DE_BITMAP, ERF_PREEN_YES, ERP_FIX, 0, 0, 0},
{ER_DE_SECONDARY_COUNT, ERF_PREEN_YES, ERP_FIX, 0, 0, 0},
{ER_DE_STREAM, ERF_PREEN_YES, ERP_DELETE, 0, 0, 0},
{ER_DE_NAME, ERF_PREEN_YES, ERP_DELETE, 0, 0, 0},
+3
View File
@@ -11,6 +11,7 @@
#define ER_BS_BOOT_REGION 0x00000002
#define ER_DE_CHECKSUM 0x00001001
#define ER_DE_UNKNOWN 0x00001002
#define ER_DE_UNUSED 0x00001003
#define ER_DE_FILE 0x00001010
#define ER_DE_SECONDARY_COUNT 0x00001011
#define ER_DE_STREAM 0x00001020
@@ -20,6 +21,8 @@
#define ER_DE_DOT_NAME 0x00001033
#define ER_DE_DUPLICATED_NAME 0x00001034
#define ER_DE_INVALID_NAME 0x00001035
#define ER_DE_UPCASE 0x00001036
#define ER_DE_BITMAP 0x00001037
#define ER_FILE_VALID_SIZE 0x00002001
#define ER_FILE_INVALID_CLUS 0x00002002
#define ER_FILE_FIRST_CLUS 0x00002003
+6
View File
@@ -68,6 +68,7 @@ int exfat_de_iter_get_dirty(struct exfat_de_iter *iter,
int ith, struct exfat_dentry **dentry);
int exfat_de_iter_flush(struct exfat_de_iter *iter);
int exfat_de_iter_advance(struct exfat_de_iter *iter, int skip_dentries);
int exfat_de_iter_revert(struct exfat_de_iter *iter, int dentries);
off_t exfat_de_iter_device_offset(struct exfat_de_iter *iter);
off_t exfat_de_iter_file_offset(struct exfat_de_iter *iter);
@@ -94,7 +95,12 @@ int exfat_add_dentry_set(struct exfat *exfat, struct exfat_dentry_loc *loc,
bool need_next_loc);
void exfat_calc_dentry_checksum(struct exfat_dentry *dentry,
uint16_t *checksum, bool primary);
uint16_t calc_dentry_set_checksum(struct exfat_dentry *dset, int dcount);
uint16_t exfat_calc_name_hash(struct exfat *exfat,
__le16 *name, int len);
int exfat_find_free_cluster(struct exfat *exfat, int clu_count,
clus_t *new_clu);
int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode,
clus_t *new_clu);
#endif
+2 -1
View File
@@ -68,7 +68,8 @@ struct buffer_desc {
char dirty[EXFAT_BITMAP_SIZE(4 * KB / 512)];
};
struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs);
struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs,
struct exfat_inode *root);
void exfat_free_exfat(struct exfat *exfat);
struct exfat_inode *exfat_alloc_inode(__u16 attr);
+9 -1
View File
@@ -54,9 +54,10 @@
#define MSDOS_UNUSED 0x00 /* end of directory */
#define EXFAT_LAST 0x00 /* end of directory */
#define EXFAT_DELETE ~(0x80)
#define EXFAT_DELETE ((~(0x80)) & 0xFF)
#define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */
#define EXFAT_INVAL 0x80 /* invalid value */
#define EXFAT_SEC (EXFAT_INVAL | (1 << 6))
#define EXFAT_BITMAP 0x81 /* allocation bitmap */
#define EXFAT_UPCASE 0x82 /* upcase table */
#define EXFAT_VOLUME 0x83 /* volume label */
@@ -69,6 +70,7 @@
#define EXFAT_ACL 0xC2 /* stream entry */
#define EXFAT_VENDOR_EXT 0xE0
#define EXFAT_VENDOR_ALLOC 0xE1
#define IS_EXFAT_SEC(x) ((x) >= EXFAT_SEC)
/* checksum types */
#define CS_DIR_ENTRY 0
@@ -238,6 +240,9 @@ struct exfat_dentry {
#define file_create_time_ms dentry.file.create_time_ms
#define file_modify_time_ms dentry.file.modify_time_ms
#define file_access_time_ms dentry.file.access_time_ms
#define file_create_tz dentry.file.create_tz
#define file_modify_tz dentry.file.modify_tz
#define file_access_tz dentry.file.access_tz
#define stream_flags dentry.stream.flags
#define stream_name_len dentry.stream.name_len
#define stream_name_hash dentry.stream.name_hash
@@ -252,5 +257,8 @@ struct exfat_dentry {
#define upcase_start_clu dentry.upcase.start_clu
#define upcase_size dentry.upcase.size
#define upcase_checksum dentry.upcase.checksum
#define vendor_alloc_flags dentry.vendor_alloc.flags
#define vendor_alloc_start_clu dentry.vendor_alloc.start_clu
#define vendor_alloc_size dentry.vendor_alloc.size
#endif /* !_EXFAT_H */
+13 -2
View File
@@ -68,6 +68,7 @@ enum {
struct exfat_blk_dev {
int dev_fd;
int verify_fd;
unsigned long long offset;
unsigned long long size;
unsigned int sector_size;
@@ -75,6 +76,7 @@ struct exfat_blk_dev {
unsigned long long num_sectors;
unsigned int num_clusters;
unsigned int cluster_size;
bool isblk;
};
struct exfat_user_input {
@@ -86,10 +88,13 @@ struct exfat_user_input {
unsigned int boundary_align;
bool pack_bitmap;
bool quick;
bool verify;
bool discard;
__u16 volume_label[VOLUME_LABEL_MAX_LEN];
int volume_label_len;
unsigned int volume_serial;
const char *guid;
unsigned char *fat_table_buff;
};
struct exfat;
@@ -155,6 +160,7 @@ int exfat_get_blk_dev_info(struct exfat_user_input *ui,
ssize_t exfat_read(int fd, void *buf, size_t size, off_t offset);
ssize_t exfat_write(int fd, void *buf, size_t size, off_t offset);
ssize_t exfat_write_zero(int fd, size_t size, off_t offset);
int exfat_discard_blocks(int fd, uint64_t start, uint64_t len);
size_t exfat_utf16_len(const __le16 *str, size_t max_size);
ssize_t exfat_utf16_enc(const char *in_str, __u16 *out_str, size_t out_size);
@@ -171,7 +177,8 @@ int exfat_read_sector(struct exfat_blk_dev *bd, void *buf,
int exfat_write_sector(struct exfat_blk_dev *bd, void *buf,
unsigned int sec_off);
int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
unsigned int checksum, bool is_backup);
struct exfat_user_input *ui, unsigned int checksum,
bool is_backup);
char *exfat_conv_volume_label(struct exfat_dentry *vol_entry);
int exfat_show_volume_serial(int fd);
int exfat_set_volume_serial(struct exfat_blk_dev *bd,
@@ -181,6 +188,8 @@ unsigned int exfat_clus_to_blk_dev_off(struct exfat_blk_dev *bd,
int exfat_get_next_clus(struct exfat *exfat, clus_t clus, clus_t *next);
int exfat_get_inode_next_clus(struct exfat *exfat, struct exfat_inode *node,
clus_t clus, clus_t *next);
int exfat_get_clus(struct exfat *exfat, struct exfat_inode *node,
clus_t index, clus_t *ret_clu);
int exfat_set_fat(struct exfat *exfat, clus_t clus, clus_t next_clus);
off_t exfat_s2o(struct exfat *exfat, off_t sect);
off_t exfat_c2o(struct exfat *exfat, unsigned int clus);
@@ -191,7 +200,9 @@ int exfat_root_clus_count(struct exfat *exfat);
int read_boot_sect(struct exfat_blk_dev *bdev, struct pbr **bs);
int exfat_parse_ulong(const char *s, unsigned long *out);
int exfat_check_name(__le16 *utf16_name, int len);
int exfat_check_written_data(struct exfat_blk_dev *bd, const void *buf,
size_t len, off_t off,
const char *what);
/*
* Exfat Print
*/
+498
View File
@@ -0,0 +1,498 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2019 Namjae Jeon <linkinjeon@kernel.org>
*/
#ifndef _UPCASE_TABLE_H
static const unsigned char default_upcase_table[EXFAT_UPCASE_TABLE_SIZE] = {
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
};
#endif /* !_UPCASE_TABLE_H */
+27
View File
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2026 Hyunchul Lee <hyc.lee@gmail.com>
*
* Portions of the progress bar code derived from ntfsprogs-plus and modified for exfatprogs.
*/
#ifndef _EXFAT_UTILS_H
#define _EXFAT_UTILS_H
#include <stdint.h>
struct progress_bar {
uint32_t start;
uint32_t stop;
uint32_t current;
uint32_t resolution;
#ifdef PROG_CALC_FLOAT
float unit;
#else
uint64_t total;
#endif
};
void progress_init(struct progress_bar *p, uint32_t start, uint32_t stop, uint32_t res);
void progress_update(struct progress_bar *p, uint32_t current);
#endif
+1 -1
View File
@@ -5,6 +5,6 @@
#ifndef _VERSION_H
#define EXFAT_PROGS_VERSION "1.2.5"
#define EXFAT_PROGS_VERSION "1.3.2"
#endif /* !_VERSION_H */
+3 -24
View File
@@ -108,45 +108,24 @@ int main(int argc, char *argv[])
}
} else {
struct exfat *exfat;
struct pbr *bs;
ret = read_boot_sect(&bd, &bs);
if (ret)
goto close_fd_out;
exfat = exfat_alloc_exfat(&bd, bs);
exfat = exfat_alloc_exfat(&bd, NULL, NULL);
if (!exfat) {
ret = -ENOMEM;
goto close_fd_out;
}
exfat->root = exfat_alloc_inode(ATTR_SUBDIR);
if (!exfat->root) {
ret = -ENOMEM;
goto free_exfat;
}
exfat->root->first_clus = le32_to_cpu(exfat->bs->bsx.root_cluster);
if (exfat_root_clus_count(exfat)) {
exfat_err("failed to follow the cluster chain of root\n");
exfat_free_inode(exfat->root);
ret = -EINVAL;
goto free_exfat;
}
/* Mode to change or display volume label */
if (flags == EXFAT_GET_VOLUME_LABEL)
ret = exfat_read_volume_label(exfat);
else if (flags == EXFAT_SET_VOLUME_LABEL)
ret = exfat_set_volume_label(exfat, argv[2]);
free_exfat:
if (exfat)
exfat_free_exfat(exfat);
exfat_free_exfat(exfat);
}
close_fd_out:
close(bd.dev_fd);
out:
return ret;
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
+1 -1
View File
@@ -1,4 +1,4 @@
AM_CFLAGS = -Wall -include $(top_builddir)/config.h -I$(top_srcdir)/include -fno-common
noinst_LIBRARIES = libexfat.a
libexfat_a_SOURCES = libexfat.c exfat_fs.c exfat_dir.c
libexfat_a_SOURCES = libexfat.c exfat_fs.c exfat_dir.c utils.c
+122 -27
View File
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include "exfat_ondisk.h"
#include "libexfat.h"
@@ -261,7 +262,6 @@ int exfat_de_iter_get(struct exfat_de_iter *iter,
int ith, struct exfat_dentry **dentry)
{
off_t next_de_file_offset;
ssize_t ret;
unsigned int block;
struct buffer_desc *bd;
@@ -275,9 +275,12 @@ int exfat_de_iter_get(struct exfat_de_iter *iter,
/* read next cluster if needed */
if (next_de_file_offset >= iter->next_read_offset) {
ret = read_block(iter, block);
if (ret != (ssize_t)iter->read_size)
return ret;
if (read_block(iter, block) != (ssize_t)iter->read_size) {
exfat_err("failed to read from device at offset %#" PRIx64 "\n",
exfat_de_iter_device_offset(iter));
return -EIO;
}
iter->next_read_offset += iter->read_size;
}
@@ -333,6 +336,63 @@ int exfat_de_iter_advance(struct exfat_de_iter *iter, int skip_dentries)
return 0;
}
/* revert @num dentries from current dentry */
int exfat_de_iter_revert(struct exfat_de_iter *iter, int num)
{
int ret;
off_t file_offset;
clus_t clu_idx, clu;
unsigned int dest_block, cur_block;
unsigned int offset;
struct buffer_desc *cur_bd, *dest_bd;
struct exfat *exfat = iter->exfat;
if (iter->de_file_offset < num * DENTRY_SIZE)
return -EINVAL;
file_offset = iter->de_file_offset - num * DENTRY_SIZE;
dest_block = (unsigned int)(file_offset / iter->read_size);
cur_block = (unsigned int)(iter->de_file_offset / iter->read_size);
/* The entries are in the same buffer_desc */
if (dest_block == cur_block)
goto out;
cur_bd = exfat_de_iter_get_buffer(iter, cur_block);
dest_bd = exfat_de_iter_get_buffer(iter, dest_block);
clu_idx = file_offset / exfat->clus_size;
if (clu_idx < iter->de_file_offset / exfat->clus_size) {
/* The entries are not in the same cluster */
ret = exfat_get_clus(exfat, iter->parent, clu_idx, &clu);
if (ret < 0)
return ret;
} else
clu = cur_bd->p_clus;
offset = (dest_block * iter->read_size) % exfat->clus_size;
/* the data of dest_block is in dest_bd */
if (dest_bd->p_clus == clu && offset == dest_bd->offset)
goto out;
/* flush then read if the data of dest_block is not in dest_bd */
exfat_de_iter_flush(iter);
dest_bd->p_clus = clu;
dest_bd->offset = offset;
if (exfat_read(exfat->blk_dev->dev_fd, dest_bd->buffer, iter->read_size,
exfat_c2o(exfat, clu) + offset) != iter->read_size)
return -EIO;
out:
iter->max_skip_dentries = 0;
iter->de_file_offset = file_offset;
iter->next_read_offset = (file_offset & ~(iter->read_size - 1)) + iter->read_size;
return 0;
}
off_t exfat_de_iter_device_offset(struct exfat_de_iter *iter)
{
struct buffer_desc *bd;
@@ -553,7 +613,7 @@ void exfat_calc_dentry_checksum(struct exfat_dentry *dentry,
}
}
static uint16_t calc_dentry_set_checksum(struct exfat_dentry *dset, int dcount)
uint16_t calc_dentry_set_checksum(struct exfat_dentry *dset, int dcount)
{
uint16_t checksum;
int i;
@@ -711,15 +771,9 @@ int exfat_update_file_dentry_set(struct exfat *exfat,
return 0;
}
static int find_free_cluster(struct exfat *exfat,
clus_t start, clus_t *new_clu)
static int __find_free_cluster(struct exfat *exfat, clus_t *new_clu,
clus_t start, clus_t end)
{
clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) +
EXFAT_FIRST_CLUSTER;
if (!exfat_heap_clus(exfat, start))
return -EINVAL;
while (start < end) {
if (exfat_bitmap_find_zero(exfat, exfat->alloc_bitmap,
start, new_clu))
@@ -729,20 +783,61 @@ static int find_free_cluster(struct exfat *exfat,
start = *new_clu + 1;
}
end = start;
start = EXFAT_FIRST_CLUSTER;
while (start < end) {
if (exfat_bitmap_find_zero(exfat, exfat->alloc_bitmap,
start, new_clu))
goto out_nospc;
if (!exfat_bitmap_get(exfat->disk_bitmap, *new_clu))
return 0;
start = *new_clu + 1;
*new_clu = EXFAT_EOF_CLUSTER;
return -ENOSPC;
}
static int find_free_cluster(struct exfat *exfat,
clus_t start, clus_t *new_clu)
{
clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) +
EXFAT_FIRST_CLUSTER;
if (!exfat_heap_clus(exfat, start))
return -EINVAL;
if (__find_free_cluster(exfat, new_clu, start, end) == 0)
return 0;
return __find_free_cluster(exfat, new_clu, EXFAT_FIRST_CLUSTER, start);
}
/* Find multiple contiguous free clusters */
int exfat_find_free_cluster(struct exfat *exfat, int clu_count,
clus_t *new_clu)
{
int ret, i;
clus_t clu;
clus_t start = EXFAT_FIRST_CLUSTER;
clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) +
EXFAT_FIRST_CLUSTER;
find_again:
ret = __find_free_cluster(exfat, &clu, start, end);
if (ret < 0)
return ret;
*new_clu = clu;
start = clu + 1;
for (i = 1; i < clu_count && start < end; i++) {
ret = __find_free_cluster(exfat, &clu, start, end);
if (ret < 0)
return ret;
if (clu != start) {
start = clu;
goto find_again;
}
start = clu + 1;
}
out_nospc:
*new_clu = EXFAT_EOF_CLUSTER;
return -ENOSPC;
if (start >= end)
return -ENOSPC;
return 0;
}
static int exfat_map_cluster(struct exfat *exfat, struct exfat_inode *inode,
@@ -828,8 +923,8 @@ static int exfat_write_dentry_set(struct exfat *exfat,
return 0;
}
static int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode,
clus_t *new_clu)
int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode,
clus_t *new_clu)
{
clus_t last_clu;
int err;
+27 -2
View File
@@ -118,17 +118,26 @@ void exfat_free_exfat(struct exfat *exfat)
if (exfat->root)
exfat_free_inode(exfat->root);
if (exfat->lookup_buffer)
free(exfat->lookup_buffer);
exfat_free_buffer(exfat, exfat->lookup_buffer);
free(exfat);
}
}
struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs)
struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs,
struct exfat_inode *root)
{
struct exfat *exfat;
if (!bs) {
if (read_boot_sect(blk_dev, &bs))
return NULL;
}
exfat = calloc(1, sizeof(*exfat));
if (!exfat) {
if (root)
exfat_free_inode(root);
free(bs);
return NULL;
}
@@ -139,6 +148,7 @@ struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs)
exfat->clus_count = le32_to_cpu(bs->bsx.clu_count);
exfat->clus_size = EXFAT_CLUSTER_SIZE(bs);
exfat->sect_size = EXFAT_SECTOR_SIZE(bs);
exfat->root = root;
/* TODO: bitmap could be very large. */
exfat->alloc_bitmap = calloc(1, EXFAT_BITMAP_SIZE(exfat->clus_count));
@@ -163,6 +173,21 @@ struct exfat *exfat_alloc_exfat(struct exfat_blk_dev *blk_dev, struct pbr *bs)
exfat_get_read_size(exfat) + 1;
exfat->start_clu = EXFAT_FIRST_CLUSTER;
if (exfat->root)
return exfat;
exfat->root = exfat_alloc_inode(ATTR_SUBDIR);
if (!exfat->root)
goto err;
exfat->root->first_clus = le32_to_cpu(exfat->bs->bsx.root_cluster);
if (exfat_root_clus_count(exfat)) {
exfat_err("failed to follow the cluster chain of root\n");
goto err;
}
return exfat;
err:
exfat_free_exfat(exfat);
+112 -7
View File
@@ -3,6 +3,9 @@
* Copyright (C) 2019 Namjae Jeon <linkinjeon@kernel.org>
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -134,6 +137,7 @@ void init_user_input(struct exfat_user_input *ui)
memset(ui, 0, sizeof(struct exfat_user_input));
ui->writeable = true;
ui->quick = true;
ui->discard = true;
}
int exfat_get_blk_dev_info(struct exfat_user_input *ui,
@@ -163,6 +167,8 @@ int exfat_get_blk_dev_info(struct exfat_user_input *ui,
char pathname[sizeof("/sys/dev/block/4294967295:4294967295/start")];
FILE *fp;
bd->isblk = true;
snprintf(pathname, sizeof(pathname), "/sys/dev/block/%u:%u/start",
major(st.st_rdev), minor(st.st_rdev));
fp = fopen(pathname, "r");
@@ -206,6 +212,16 @@ int exfat_get_blk_dev_info(struct exfat_user_input *ui,
ret = 0;
bd->dev_fd = fd;
if (ui->verify) {
bd->verify_fd = open(ui->dev_name, O_RDONLY|O_DIRECT);
if (bd->verify_fd < 0) {
exfat_err("open %s O_DIRECT failed:%s\n", ui->dev_name,
strerror(errno));
close(fd);
ret = -1;
}
}
out:
return ret;
}
@@ -238,6 +254,15 @@ ssize_t exfat_write_zero(int fd, size_t size, off_t offset)
return 0;
}
int exfat_discard_blocks(int fd, uint64_t start, uint64_t len)
{
uint64_t range[2] = { start, len };
if (ioctl(fd, BLKDISCARD, &range) < 0)
return errno;
return 0;
}
size_t exfat_utf16_len(const __le16 *str, size_t max_size)
{
size_t i = 0;
@@ -410,8 +435,10 @@ char *exfat_conv_volume_label(struct exfat_dentry *vol_entry)
__le16 disk_label[VOLUME_LABEL_MAX_LEN];
volume_label = malloc(VOLUME_LABEL_BUFFER_SIZE);
if (!volume_label)
if (!volume_label) {
exfat_err("Cannot allocate volume_label: out of memory\n");
return NULL;
}
memcpy(disk_label, vol_entry->vol_label, sizeof(disk_label));
memset(volume_label, 0, VOLUME_LABEL_BUFFER_SIZE);
@@ -684,6 +711,45 @@ out:
return err;
}
int exfat_check_written_data(struct exfat_blk_dev *bd,
const void *buf, size_t len,
off_t off, const char *what)
{
void *verify;
ssize_t n;
size_t sector = bd->sector_size;
int ret = 0;
ret = fsync(bd->dev_fd);
if (ret)
return ret;
off_t aligned_off = off & ~(sector - 1);
size_t head = off - aligned_off;
size_t aligned_len = ((head + len + sector - 1) / sector) * sector;
if (posix_memalign(&verify, sector, aligned_len))
return -ENOMEM;
memset(verify, 0, aligned_len);
n = exfat_read(bd->verify_fd, verify, aligned_len, aligned_off);
if (n != (ssize_t)aligned_len) {
exfat_debug("%s verify read failed (off=%llu, len=%zu)\n",
what, (unsigned long long)aligned_off,
aligned_len);
ret = -EIO;
}
if (memcmp(buf, (unsigned char *)verify + head, len) != 0) {
exfat_debug("%s verify mismatch (off=%llu)\n",
what, (unsigned long long)off);
ret = -EIO;
}
free(verify);
return ret;
}
int exfat_read_sector(struct exfat_blk_dev *bd, void *buf, unsigned int sec_off)
{
int ret;
@@ -715,7 +781,8 @@ int exfat_write_sector(struct exfat_blk_dev *bd, void *buf,
}
int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
unsigned int checksum, bool is_backup)
struct exfat_user_input *ui, unsigned int checksum,
bool is_backup)
{
__le32 *checksum_buf;
int ret = 0;
@@ -723,8 +790,10 @@ int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
unsigned int sec_idx = CHECKSUM_SEC_IDX;
checksum_buf = malloc(bd->sector_size);
if (!checksum_buf)
if (!checksum_buf) {
exfat_err("Cannot allocate checksum_buf: out of memory\n");
return -1;
}
if (is_backup)
sec_idx += BACKUP_BOOT_SEC_IDX;
@@ -738,6 +807,17 @@ int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
goto free;
}
if (ui && ui->verify) {
ret = exfat_check_written_data(bd,
checksum_buf, bd->sector_size,
sec_idx * bd->sector_size,
"checksum sector");
if (ret) {
exfat_err("checksum sector verification failed (read-back mismatch)\n");
goto free;
}
}
free:
free(checksum_buf);
return ret;
@@ -775,7 +855,8 @@ free_ppbr:
return ret;
}
static int exfat_update_boot_checksum(struct exfat_blk_dev *bd, bool is_backup)
static int exfat_update_boot_checksum(struct exfat_blk_dev *bd,
struct exfat_user_input *ui, bool is_backup)
{
unsigned int checksum = 0;
int ret, sec_idx, backup_sec_idx = 0;
@@ -807,7 +888,7 @@ static int exfat_update_boot_checksum(struct exfat_blk_dev *bd, bool is_backup)
&checksum);
}
ret = exfat_write_checksum_sector(bd, checksum, is_backup);
ret = exfat_write_checksum_sector(bd, ui, checksum, is_backup);
free_buf:
free(buf);
@@ -861,13 +942,13 @@ int exfat_set_volume_serial(struct exfat_blk_dev *bd,
goto free_ppbr;
}
ret = exfat_update_boot_checksum(bd, 0);
ret = exfat_update_boot_checksum(bd, ui, 0);
if (ret < 0) {
exfat_err("main checksum update failed\n");
goto free_ppbr;
}
ret = exfat_update_boot_checksum(bd, 1);
ret = exfat_update_boot_checksum(bd, ui, 1);
if (ret < 0)
exfat_err("backup checksum update failed\n");
free_ppbr:
@@ -905,6 +986,30 @@ int exfat_get_next_clus(struct exfat *exfat, clus_t clus, clus_t *next)
return 0;
}
int exfat_get_clus(struct exfat *exfat, struct exfat_inode *node,
clus_t index, clus_t *ret_clu)
{
int ret;
clus_t clu = node->first_clus;
if (node->is_contiguous) {
*ret_clu = clu + index;
return 0;
}
while (index) {
ret = exfat_get_next_clus(exfat, clu, &clu);
if (ret)
return ret;
index--;
}
*ret_clu = clu;
return 0;
}
int exfat_get_inode_next_clus(struct exfat *exfat, struct exfat_inode *node,
clus_t clus, clus_t *next)
{
+66
View File
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2026 Hyunchul Lee <hyc.lee@gmail.com>
*
* Portions of the progress bar code derived from ntfsprogs-plus and modified for exfatprogs.
*/
#include <stdio.h>
#include <inttypes.h>
#include "utils.h"
void progress_init(struct progress_bar *p, uint32_t start, uint32_t stop, uint32_t res)
{
uint64_t total;
p->start = start;
p->stop = stop;
p->current = start;
total = stop - start + 1;
if (total <= 0)
total = 1;
#ifdef PROG_CALC_FLOAT
p->unit = 100.0 / total;
if (((res * 100 * 100) / total) == 0)
p->resolution = (int)(total / (100 * 100.0)); // 0.01 resolution
else
p->resolution = res;
#else
p->total = total;
if (((res * 100) / p->total) == 0) {
p->resolution = p->total / 100;
if (!p->resolution)
p->resolution = 1;
} else
p->resolution = res;
#endif
}
void progress_update(struct progress_bar *p, uint32_t update)
{
#ifdef PROG_CALC_FLOAT
float percent;
#else
uint32_t percent;
#endif
p->current += update;
if (p->current != p->stop) {
if ((p->current - p->start) % p->resolution)
return;
#ifdef PROG_CALC_FLOAT
percent = p->unit * p->current;
printf("%6.2f percent completed\r", percent);
#else
percent = (p->current * 100) / p->total;
printf("%3u percent completed\r", percent);
#endif
} else
printf("100.00 percent completed\n");
fflush(stdout);
}
+90
View File
@@ -0,0 +1,90 @@
.TH defrag.exfat 8
.SH NAME
defrag.exfat \- Defragment or assess fragmentation on an exFAT filesystem
.SH SYNOPSIS
.B defrag.exfat
[\fB\-f\fR | \fB\-a\fR]
.I device
.P
.B defrag.exfat
\fB\-h\fR | \fB\-\-help\fR
.P
.B defrag.exfat
\fB\-v\fR | \fB\-\-version\fR
.SH DESCRIPTION
.B defrag.exfat
is a utility to defragment files on an exFAT-formatted device or assess its fragmentation status.
When no option is specified, the tool warns the user to run \fBfsck.exfat\fR first for filesystem consistency.
This safety prompt can be bypassed using the \fB\-f\fR option.
The \fB\-a\fR option enables assessment mode, which analyzes fragmentation without modifying the filesystem.
\fBdefrag.exfat\fR provides whole-disk defragmentation based on cluster swapping, which incurs a certain amount of wear overhead on flash-based storage devices with low fragmentation levels.
Therefore, it is recommended to use \fBdefrag.exfat\fR on mechanical hard disk drives (HDDs) or flash-based devices that exhibit a relatively high degree of fragmentation.
.SH OPTIONS
.TP
.B \-f, \-\-force
Perform defragmentation without prompting the fsck warning. Use with caution.
.TP
.B \-a, \-\-assessment
Assess the fragmentation status of the exFAT volume without making any changes.
.TP
.B \-v, \-\-version
Display version information and exit.
.TP
.B \-h, \-\-help
Show usage information and exit.
.SH EXAMPLES
.PP
Defragment an unmounted exFAT device (with safety warning):
.EX
$ defrag.exfat /dev/sda1
.EE
.PP
Defragment without prompting (force mode):
.EX
$ defrag.exfat -f /dev/sda1
.EE
.PP
Assess fragmentation status (read-only):
.EX
$ defrag.exfat -a /dev/sda1
.EE
.PP
Show version:
.EX
$ defrag.exfat -v
.EE
.PP
Show help:
.EX
$ defrag.exfat -h
.EE
.SH NOTES
Before defragmentation:
.IP -
The target device must be \fBunmounted\fR.
.IP -
Please run \fBfsck.exfat\fR on the target device to ensure filesystem integrity.
.IP -
Considering the potential risks of defragmentation, critical data should be \fBbacked up\fR in advance.
.PP
During defragmentation:
.IP -
Always keep the device \fBconnected and powered\fR.
.IP -
If the device is removed, powered off, or experiences a hardware failure, the filesystem may become corrupted.
.PP
+25
View File
@@ -3,6 +3,17 @@
dump.exfat \- Show on-disk information of exfat filesystem
.SH SYNOPSIS
.B dump.exfat
[
.B \-d
.I file-path
]
[
.B \-s
.I dir-path
]
[
.B \-r
]
.I device
.br
.B dump.exfat \-V
@@ -10,8 +21,22 @@ dump.exfat \- Show on-disk information of exfat filesystem
.B dump.exfat
Print on-disk information from given device that formatted by exFAT filesystem.
Note: For printing information of directory entries, the absence of "double-link" does not indicate the cluster is not doubly allocated if the scan is not started from the root directory with the recursive option.
.PP
.SH OPTIONS
.TP
.B \-V
Prints the version number and exits.
.TP
.BR \-d ", " \-\-dentry-set=\fIpath\fR
Print information of directory entries from a given path that exits in the given device.
.TP
.BR \-s ", " \-\-scan-dir=\fIdir-path\fR
Scan and print information of directory entries from a given path that exits in the given device.
.TP
.BR \-r ", " \-\-recursive
Scan and print information of directory entries from a given path recursively that exits in the given device. Only works with -s option.
.TP
.BR \-c ", " \-\-cluster-chain
Print the cluster chain while printing the directory entry information. Only works with -d/-s option.
+5
View File
@@ -16,6 +16,8 @@ fsck.exfat \- check an exFAT filesystem
] [
.B \-b
] [
.B \-P
] [
.B \-v
]
.I device
@@ -59,6 +61,9 @@ Check the filesystem but do not attempt to repair the filesystem.
.BI \-p
Repair the filesystem without user interaction if it can be done safely.
.TP
.BI \-P
Show progress bar while checking the filesystem. Cannot be used with -r option.
.TP
.BI \-r
Repair the filesystem interactively.
.TP
+21
View File
@@ -1,3 +1,4 @@
'\" t
.TH mkfs.exfat 8
.SH NAME
mkfs.exfat \- create an exFAT filesystem
@@ -15,6 +16,8 @@ mkfs.exfat \- create an exFAT filesystem
] [
.B \-f
] [
.B \-C
] [
.B \-h
] [
.B \-L
@@ -102,6 +105,20 @@ _
.BR \-f ", " \-\-full\-format
Performs a full format.
This zeros the entire disk device while creating the exFAT filesystem.
.TE
.TP
.BR \-K ", " \-\-no\-discard
Do not attempt to discard blocks.
.TP
.BR \-C ", " \-\-verify\-written
Verify filesystem metadata by reading it back after writing.
This option performs read-back verification of critical exFAT metadata
(boot record, FAT, allocation bitmap, upcase table, and root directory)
after each formatting stage.
It is useful for detecting broken storage devices or devices that falsely
report successful writes without actually persisting data.
This option may slightly degrade formatting performance and is therefore
disabled by default.
.TP
.BR \-h ", " \-\-help
Prints the help and exit.
@@ -111,6 +128,10 @@ Specifies the volume label to be associated with the exFAT filesystem.
.TP
.BR \-U ", " \-\-volume\-guid =\fIguid\fR
Specifies the volume GUID to be associated with the exFAT filesystem.
It can be given in the standard, hypenized UUID format like
\fBaaaabbbb-cccc-dddd-eeee-ffff00001111\fR. Note: The volume GUID cannot be used
to set the the 8-letter ID reported by \fIblkid\fR or used as
the filesystem UUID in \fB/etc/fstab\fR.
.TP
.B \-\-pack\-bitmap
Attempts to relocate the exFAT allocation bitmap so that it ends at the
+233 -48
View File
@@ -127,6 +127,17 @@ static int exfat_write_boot_sector(struct exfat_blk_dev *bd,
goto free_ppbr;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
ppbr, bd->sector_size,
sec_idx * bd->sector_size,
"boot sector");
if (ret) {
exfat_err("boot sector verification failed (read-back mismatch)\n");
goto free_ppbr;
}
}
boot_calc_checksum((unsigned char *)ppbr, bd->sector_size,
true, checksum);
@@ -136,7 +147,8 @@ free_ppbr:
}
static int exfat_write_extended_boot_sectors(struct exfat_blk_dev *bd,
unsigned int *checksum, bool is_backup)
struct exfat_user_input *ui, unsigned int *checksum,
bool is_backup)
{
char *peb;
__le16 *peb_signature;
@@ -145,8 +157,10 @@ static int exfat_write_extended_boot_sectors(struct exfat_blk_dev *bd,
unsigned int sec_idx = EXBOOT_SEC_IDX;
peb = malloc(bd->sector_size);
if (!peb)
if (!peb) {
exfat_err("Cannot allocate peb: out of memory\n");
return -1;
}
if (is_backup)
sec_idx += BACKUP_BOOT_SEC_IDX;
@@ -161,6 +175,17 @@ static int exfat_write_extended_boot_sectors(struct exfat_blk_dev *bd,
goto free_peb;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
peb, bd->sector_size,
(sec_idx - 1) * bd->sector_size,
"extended boot sector");
if (ret) {
exfat_err("extended boot sector verification failed (read-back mismatch)\n");
goto free_peb;
}
}
boot_calc_checksum((unsigned char *) peb, bd->sector_size,
false, checksum);
}
@@ -171,20 +196,20 @@ free_peb:
}
static int exfat_write_oem_sector(struct exfat_blk_dev *bd,
unsigned int *checksum, bool is_backup)
struct exfat_user_input *ui, unsigned int *checksum,
bool is_backup)
{
char *oem;
int ret = 0;
unsigned int sec_idx = OEM_SEC_IDX;
oem = malloc(bd->sector_size);
oem = calloc(1, bd->sector_size);
if (!oem)
return -1;
if (is_backup)
sec_idx += BACKUP_BOOT_SEC_IDX;
memset(oem, 0xFF, bd->sector_size);
ret = exfat_write_sector(bd, oem, sec_idx);
if (ret) {
exfat_err("oem sector write failed\n");
@@ -192,11 +217,21 @@ static int exfat_write_oem_sector(struct exfat_blk_dev *bd,
goto free_oem;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
oem, bd->sector_size,
sec_idx * bd->sector_size,
"oem sector");
if (ret) {
exfat_err("oem sector verification failed (read-back mismatch)\n");
goto free_oem;
}
}
boot_calc_checksum((unsigned char *)oem, bd->sector_size, false,
checksum);
/* Zero out reserved sector */
memset(oem, 0, bd->sector_size);
/* Reuse zeroed out oem sector for reserved sector */
ret = exfat_write_sector(bd, oem, sec_idx + 1);
if (ret) {
exfat_err("reserved sector write failed\n");
@@ -204,6 +239,17 @@ static int exfat_write_oem_sector(struct exfat_blk_dev *bd,
goto free_oem;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
oem, bd->sector_size,
(sec_idx + 1) * bd->sector_size,
"reserved sector");
if (ret) {
exfat_err("reserved sector verification failed (read-back mismatch)\n");
goto free_oem;
}
}
boot_calc_checksum((unsigned char *)oem, bd->sector_size, false,
checksum);
@@ -221,18 +267,18 @@ static int exfat_create_volume_boot_record(struct exfat_blk_dev *bd,
ret = exfat_write_boot_sector(bd, ui, &checksum, is_backup);
if (ret)
return ret;
ret = exfat_write_extended_boot_sectors(bd, &checksum, is_backup);
ret = exfat_write_extended_boot_sectors(bd, ui, &checksum, is_backup);
if (ret)
return ret;
ret = exfat_write_oem_sector(bd, &checksum, is_backup);
ret = exfat_write_oem_sector(bd, ui, &checksum, is_backup);
if (ret)
return ret;
return exfat_write_checksum_sector(bd, checksum, is_backup);
return exfat_write_checksum_sector(bd, ui, checksum, is_backup);
}
static int write_fat_entry(int fd, __le32 clu,
unsigned long long offset)
static int write_fat_entry(struct exfat_user_input *ui, int fd,
__le32 clu, unsigned long long offset)
{
int nbyte;
off_t fat_entry_offset = finfo.fat_byte_off + (offset * sizeof(__le32));
@@ -244,6 +290,11 @@ static int write_fat_entry(int fd, __le32 clu,
return -1;
}
if (ui->verify) {
memcpy(ui->fat_table_buff + offset * sizeof(__le32),
(__u8 *)&clu, sizeof(__le32));
}
return 0;
}
@@ -256,12 +307,12 @@ static int write_fat_entries(struct exfat_user_input *ui, int fd,
count = clu + round_up(length, ui->cluster_size) / ui->cluster_size;
for (; clu < count - 1; clu++) {
ret = write_fat_entry(fd, cpu_to_le32(clu + 1), clu);
ret = write_fat_entry(ui, fd, cpu_to_le32(clu + 1), clu);
if (ret)
return ret;
}
ret = write_fat_entry(fd, cpu_to_le32(EXFAT_EOF_CLUSTER), clu);
ret = write_fat_entry(ui, fd, cpu_to_le32(EXFAT_EOF_CLUSTER), clu);
if (ret)
return ret;
@@ -272,52 +323,87 @@ static int exfat_create_fat_table(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
int ret, clu;
unsigned int fat_table_entries = 0;
if (ui->verify) {
fat_table_entries =
EXFAT_FIRST_CLUSTER +
DIV_ROUND_UP(finfo.bitmap_byte_len, ui->cluster_size) +
DIV_ROUND_UP(finfo.ut_byte_len, ui->cluster_size) +
DIV_ROUND_UP(finfo.root_byte_len, ui->cluster_size);
ui->fat_table_buff = calloc(fat_table_entries, sizeof(__le32));
if (!ui->fat_table_buff)
return -ENOMEM;
}
/* fat entry 0 should be media type field(0xF8) */
ret = write_fat_entry(bd->dev_fd, cpu_to_le32(0xfffffff8), 0);
ret = write_fat_entry(ui, bd->dev_fd, cpu_to_le32(0xfffffff8), 0);
if (ret) {
exfat_err("fat 0 entry write failed\n");
return ret;
goto free_fat_table_buff;
}
/* fat entry 1 is historical precedence(0xFFFFFFFF) */
ret = write_fat_entry(bd->dev_fd, cpu_to_le32(0xffffffff), 1);
ret = write_fat_entry(ui, bd->dev_fd, cpu_to_le32(0xffffffff), 1);
if (ret) {
exfat_err("fat 1 entry write failed\n");
return ret;
goto free_fat_table_buff;
}
/* write bitmap entries */
clu = write_fat_entries(ui, bd->dev_fd, EXFAT_FIRST_CLUSTER,
finfo.bitmap_byte_len);
if (clu < 0)
return ret;
if (clu < 0) {
ret = clu;
goto free_fat_table_buff;
}
/* write upcase table entries */
clu = write_fat_entries(ui, bd->dev_fd, clu + 1, finfo.ut_byte_len);
if (clu < 0)
return ret;
if (clu < 0) {
ret = clu;
goto free_fat_table_buff;
}
/* write root directory entries */
clu = write_fat_entries(ui, bd->dev_fd, clu + 1, finfo.root_byte_len);
if (clu < 0)
return ret;
if (clu < 0) {
ret = clu;
goto free_fat_table_buff;
}
finfo.used_clu_cnt = clu + 1;
finfo.used_clu_cnt = clu + 1 - EXFAT_FIRST_CLUSTER;
exfat_debug("Total used cluster count : %d\n", finfo.used_clu_cnt);
if (ui->verify) {
ret = exfat_check_written_data(bd,
ui->fat_table_buff, fat_table_entries * sizeof(__le32),
finfo.fat_byte_off,
"fat table");
if (ret)
exfat_err("fat table verification failed (read-back mismatch)\n");
}
free_fat_table_buff:
if (ui->verify)
free(ui->fat_table_buff);
return ret;
}
static int exfat_create_bitmap(struct exfat_blk_dev *bd)
static int exfat_create_bitmap(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
char *bitmap;
unsigned int full_bytes, rem_bits, zero_offset;
unsigned int nbytes;
int ret = 0;
bitmap = malloc(finfo.bitmap_byte_len);
if (!bitmap)
if (!bitmap) {
exfat_err("Cannot allocate bitmap: out of memory\n");
return -1;
}
full_bytes = finfo.used_clu_cnt / 8;
rem_bits = finfo.used_clu_cnt % 8;
@@ -342,6 +428,18 @@ static int exfat_create_bitmap(struct exfat_blk_dev *bd)
return -1;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
bitmap, finfo.bitmap_byte_len,
finfo.bitmap_byte_off,
"bitmap");
if (ret) {
exfat_err("bitmap verification failed (read-back mismatch)\n");
free(bitmap);
return ret;
}
}
free(bitmap);
return 0;
}
@@ -351,7 +449,15 @@ static int exfat_create_root_dir(struct exfat_blk_dev *bd,
{
struct exfat_dentry ed[4] = {0};
int dentries_len = sizeof(ed);
int nbytes;
int nbytes, ret;
ret = exfat_write_zero(bd->dev_fd, ui->cluster_size,
finfo.root_byte_off);
if (ret) {
exfat_err("zero out write failed for root dir (errno : %d)\n",
errno);
return ret;
}
/* Set volume label entry */
ed[0].type = EXFAT_VOLUME;
@@ -390,6 +496,17 @@ static int exfat_create_root_dir(struct exfat_blk_dev *bd,
return -1;
}
if (ui->verify) {
ret = exfat_check_written_data(bd,
ed, dentries_len,
finfo.root_byte_off,
"root directory");
if (ret) {
exfat_err("root directory verification failed (read-back mismatch)\n");
return ret;
}
}
return 0;
}
@@ -403,6 +520,8 @@ static void usage(void)
"\t-b | --boundary-align=size(or suffixed by 'K' or 'M') Specify boundary alignment\n"
"\t --pack-bitmap Move bitmap into FAT segment\n"
"\t-f | --full-format Full format\n"
"\t-C | --check-written Verify written filesystem metadata by read-back\n"
"\t-K | --no-discard Do not discard blocks\n"
"\t-V | --version Show version\n"
"\t-q | --quiet Print only errors\n"
"\t-v | --verbose Print debug\n"
@@ -422,6 +541,8 @@ static const struct option opts[] = {
{"boundary-align", required_argument, NULL, 'b' },
{"pack-bitmap", no_argument, NULL, PACK_BITMAP },
{"full-format", no_argument, NULL, 'f' },
{"check-written", no_argument, NULL, 'C' },
{"no-discard", no_argument, NULL, 'K' },
{"version", no_argument, NULL, 'V' },
{"quiet", no_argument, NULL, 'q' },
{"verbose", no_argument, NULL, 'v' },
@@ -438,8 +559,8 @@ static const struct option opts[] = {
*/
static int exfat_pack_bitmap(const struct exfat_user_input *ui)
{
unsigned int fat_byte_end = finfo.fat_byte_off + finfo.fat_byte_len,
bitmap_byte_len = finfo.bitmap_byte_len,
unsigned long long fat_byte_end = finfo.fat_byte_off + finfo.fat_byte_len;
unsigned int bitmap_byte_len = finfo.bitmap_byte_len,
bitmap_clu_len = round_up(bitmap_byte_len, ui->cluster_size),
bitmap_clu_cnt, total_clu_cnt, new_bitmap_clu_len;
@@ -481,19 +602,21 @@ static int exfat_build_mkfs_info(struct exfat_blk_dev *bd,
bd->sector_size);
return -1;
}
finfo.fat_byte_off = round_up(bd->offset + 24 * bd->sector_size,
ui->boundary_align) - bd->offset;
max_clusters = (bd->size - finfo.fat_byte_off - 8 * num_fats - 1) /
(ui->cluster_size + 4 * num_fats) + 1;
finfo.fat_byte_len = round_up((max_clusters + 2) * 4,
(unsigned long long)bd->sector_size);
/* Prevent integer overflow when computing the FAT length */
if (max_clusters > UINT_MAX / 4 - 2) {
if (finfo.fat_byte_len / bd->sector_size > UINT_MAX) {
exfat_err("cluster size (%u bytes) is too small\n", ui->cluster_size);
return -1;
}
finfo.fat_byte_len = round_up((max_clusters + 2) * 4, bd->sector_size);
finfo.clu_byte_off = round_up(bd->offset + finfo.fat_byte_off +
finfo.fat_byte_len * num_fats, ui->boundary_align) - bd->offset;
finfo.fat_byte_len * num_fats,
(unsigned long long)ui->boundary_align) - bd->offset;
if (bd->size <= finfo.clu_byte_off) {
exfat_err("boundary alignment is too big\n");
return -1;
@@ -509,12 +632,14 @@ static int exfat_build_mkfs_info(struct exfat_blk_dev *bd,
finfo.bitmap_byte_len = round_up(finfo.total_clu_cnt, 8) / 8;
if (ui->pack_bitmap)
exfat_pack_bitmap(ui);
clu_len = round_up(finfo.bitmap_byte_len, ui->cluster_size);
clu_len = round_up(finfo.bitmap_byte_len,
(unsigned long long)ui->cluster_size);
finfo.ut_start_clu = EXFAT_FIRST_CLUSTER + clu_len / ui->cluster_size;
finfo.ut_byte_off = finfo.bitmap_byte_off + clu_len;
finfo.ut_byte_len = EXFAT_UPCASE_TABLE_SIZE;
clu_len = round_up(finfo.ut_byte_len, ui->cluster_size);
clu_len = round_up(finfo.ut_byte_len,
(unsigned long long)ui->cluster_size);
finfo.root_start_clu = finfo.ut_start_clu + clu_len / ui->cluster_size;
finfo.root_byte_off = finfo.ut_byte_off + clu_len;
@@ -528,25 +653,71 @@ static int exfat_zero_out_disk(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
int ret;
unsigned long long total_written = 0;
unsigned long long size;
if (ui->quick)
size = finfo.root_byte_off + ui->cluster_size;
else
size = bd->size;
return 0;
ret = exfat_write_zero(bd->dev_fd, size, 0);
ret = exfat_write_zero(bd->dev_fd, bd->size, 0);
if (ret) {
exfat_err("write failed(errno : %d)\n", errno);
return ret;
}
exfat_debug("zero out written size : %llu, disk size : %llu\n",
total_written, bd->size);
exfat_debug("zero out written size : %llu\n",
bd->size);
return 0;
}
static void exfat_discard_dev(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
uint64_t offset = 0;
uint64_t tmp_step;
int err;
/* Discard the device 2G at a time */
const uint64_t step = 2ULL << 30;
const uint64_t count = bd->num_sectors * bd->sector_size;
if (!ui->discard || !bd->isblk) {
exfat_debug("no-discard requested or the device is a file\n");
return;
}
/*
* The block discarding happens in smaller batches so it can be
* interrupted prematurely
*/
while (offset < count) {
tmp_step = count - offset;
if (step < tmp_step)
tmp_step = step;
err = exfat_discard_blocks(bd->dev_fd, offset, tmp_step);
/*
* We intentionally ignore errors from the discard ioctl. It is
* not necessary for the mkfs functionality but just an
* optimization. However we should stop on error.
*/
if (err == 0) {
if (offset == 0) {
exfat_info("Discarding blocks: ");
exfat_debug("BLKDISCARD: ");
}
exfat_debug("%"PRIu64"-%"PRIu64" ", offset, offset + tmp_step);
fflush(stdout);
} else {
exfat_debug("BLKDISCARD: %s\n", strerror(err));
if (offset > 0)
exfat_info("\n");
return;
}
offset += tmp_step;
}
if (offset > 0)
exfat_info("done\n");
}
static int make_exfat(struct exfat_blk_dev *bd, struct exfat_user_input *ui)
{
int ret;
@@ -574,13 +745,13 @@ static int make_exfat(struct exfat_blk_dev *bd, struct exfat_user_input *ui)
return ret;
exfat_info("Allocation bitmap creation: ");
ret = exfat_create_bitmap(bd);
ret = exfat_create_bitmap(bd, ui);
exfat_info("%s\n", ret ? "failed" : "done");
if (ret)
return ret;
exfat_info("Upcase table creation: ");
ret = exfat_create_upcase_table(bd);
ret = exfat_create_upcase_table(bd, ui);
exfat_info("%s\n", ret ? "failed" : "done");
if (ret)
return ret;
@@ -634,7 +805,7 @@ int main(int argc, char *argv[])
exfat_err("failed to init locale/codeset\n");
opterr = 0;
while ((c = getopt_long(argc, argv, "n:L:U:s:c:b:fVqvh", opts, NULL)) != EOF)
while ((c = getopt_long(argc, argv, "n:L:U:s:c:b:fCKVqvh", opts, NULL)) != EOF)
switch (c) {
/*
* Make 'n' option fallthrough to 'L' option for for backward
@@ -703,6 +874,12 @@ int main(int argc, char *argv[])
case 'f':
ui.quick = false;
break;
case 'C':
ui.verify = true;
break;
case 'K':
ui.discard = false;
break;
case 'V':
version_only = true;
break;
@@ -747,6 +924,12 @@ int main(int argc, char *argv[])
if (ret)
goto close;
exfat_discard_dev(&bd, &ui);
/*
* Zeroing out still needs to be conducted as per JESD84-B51 6.6.9:
* "content of an explicitly erased memory range shall be 0 or 1
* depending on different memory technology,"
*/
ret = exfat_zero_out_disk(&bd, &ui);
if (ret)
goto close;
@@ -759,10 +942,12 @@ int main(int argc, char *argv[])
ret = fsync(bd.dev_fd);
close:
close(bd.dev_fd);
if (ui.verify)
close(bd.verify_fd);
out:
if (!ret)
exfat_info("\nexFAT format complete!\n");
else
exfat_err("\nexFAT format fail!\n");
return ret;
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
+6 -7
View File
@@ -12,15 +12,14 @@ struct exfat_mkfs_info {
unsigned int total_clu_cnt;
unsigned int used_clu_cnt;
unsigned int fat_byte_off;
unsigned int fat_byte_len;
unsigned int clu_byte_off;
unsigned int bitmap_byte_off;
unsigned long long fat_byte_len;
unsigned long long clu_byte_off;
unsigned long long bitmap_byte_off;
unsigned int bitmap_byte_len;
unsigned int ut_byte_off;
unsigned long long ut_byte_off;
unsigned int ut_start_clu;
unsigned int ut_clus_off;
unsigned int ut_byte_len;
unsigned int root_byte_off;
unsigned long long root_byte_off;
unsigned int root_byte_len;
unsigned int root_start_clu;
unsigned int volume_serial;
@@ -28,6 +27,6 @@ struct exfat_mkfs_info {
extern struct exfat_mkfs_info finfo;
int exfat_create_upcase_table(struct exfat_blk_dev *bd);
int exfat_create_upcase_table(struct exfat_blk_dev *bd, struct exfat_user_input *ui);
#endif /* !_MKFS_H */
+18 -492
View File
@@ -11,504 +11,30 @@
#include "exfat_ondisk.h"
#include "libexfat.h"
#include "mkfs.h"
#include "upcase_table.h"
static const unsigned char upcase_table[EXFAT_UPCASE_TABLE_SIZE] = {
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
};
int exfat_create_upcase_table(struct exfat_blk_dev *bd)
int exfat_create_upcase_table(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
int nbytes;
int ret;
nbytes = pwrite(bd->dev_fd, upcase_table, EXFAT_UPCASE_TABLE_SIZE, finfo.ut_byte_off);
nbytes = pwrite(bd->dev_fd, default_upcase_table,
EXFAT_UPCASE_TABLE_SIZE, finfo.ut_byte_off);
if (nbytes != EXFAT_UPCASE_TABLE_SIZE)
return -1;
if (ui->verify) {
ret = exfat_check_written_data(bd,
default_upcase_table,
EXFAT_UPCASE_TABLE_SIZE,
finfo.ut_byte_off,
"upcase table");
if (ret) {
exfat_err("upcase table verification failed (read-back mismatch)\n");
return ret;
}
}
return 0;
}
Binary file not shown.
+27 -13
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
TESTCASE_DIR=$1
TESTCASE=$1
NEED_LOOPDEV=$2
IMAGE_FILE=exfat.img
FSCK_PROG=${FSCK1:-"fsck.exfat"}
@@ -19,24 +19,38 @@ cleanup() {
}
if [ $# -eq 0 ]; then
TESTCASE_DIRS=$(find . -mindepth 1 -maxdepth 1 -type d)
TEST_COUNT=$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)
TESTCASE_LIST=($(find . -name "${IMAGE_FILE}.tar.xz" -exec dirname {} \;))
TESTCASE_LIST+=($(find . -name "[[:digit:]]*.sh" | sort))
else
TESTCASE_DIRS=$@
TEST_COUNT=$#
TESTCASE_LIST=($@)
fi
for TESTCASE_DIR in $TESTCASE_DIRS; do
if [ ! -e "${TESTCASE_DIR}/${IMAGE_FILE}.tar.xz" ]; then
TEST_COUNT=${#TESTCASE_LIST[*]}
for TESTCASE in ${TESTCASE_LIST[*]}; do
if [ ! -e "${TESTCASE}/${IMAGE_FILE}.tar.xz" -a ! -e ${TESTCASE} ]; then
TEST_COUNT=$((TEST_COUNT - 1))
continue
fi
echo "Running ${TESTCASE_DIR}"
echo "Running ${TESTCASE}"
echo "-----------------------------------"
# Create a corrupted image
rm -f ${IMAGE_FILE}
if [ -e "${TESTCASE}/${IMAGE_FILE}.tar.xz" ]; then
tar -C . -xf "${TESTCASE}/${IMAGE_FILE}.tar.xz"
else
./${TESTCASE} ${IMAGE_FILE}
fi
if [ ! -e ${IMAGE_FILE} ]; then
echo ""
echo "Failed to create corrupted image"
cleanup
fi
# Set up image file as loop device
tar -C . -xf "${TESTCASE_DIR}/${IMAGE_FILE}.tar.xz"
if [ $NEED_LOOPDEV ]; then
DEV_FILE=$(losetup -f "${IMAGE_FILE}" --show)
else
@@ -47,7 +61,7 @@ for TESTCASE_DIR in $TESTCASE_DIRS; do
$FSCK_PROG "$DEV_FILE" | grep -q "ERROR:\|corrupted"
if [ $? -ne 0 ]; then
echo ""
echo "Failed to detect corruption for ${TESTCASE_DIR}"
echo "Failed to detect corruption for ${TESTCASE}"
if [ $NEED_LOOPDEV ]; then
losetup -d "${DEV_FILE}"
fi
@@ -58,7 +72,7 @@ for TESTCASE_DIR in $TESTCASE_DIRS; do
$FSCK_PROG $FSCK_OPTS "$DEV_FILE"
if [ $? -ne 1 ] && [ $? -ne 0 ]; then
echo ""
echo "Failed to repair ${TESTCASE_DIR}"
echo "Failed to repair ${TESTCASE}"
if [ $NEED_LOOPDEV ]; then
losetup -d "${DEV_FILE}"
fi
@@ -70,7 +84,7 @@ for TESTCASE_DIR in $TESTCASE_DIRS; do
$FSCK_PROG_2 "$DEV_FILE"
if [ $? -ne 0 ]; then
echo ""
echo "Failed, corrupted ${TESTCASE_DIR}"
echo "Failed, corrupted ${TESTCASE}"
if [ $NEED_LOOPDEV ]; then
losetup -d "${DEV_FILE}"
fi
@@ -78,7 +92,7 @@ for TESTCASE_DIR in $TESTCASE_DIRS; do
fi
echo ""
echo "Passed ${TESTCASE_DIR}"
echo "Passed ${TESTCASE}"
PASS_COUNT=$((PASS_COUNT + 1))
if [ $NEED_LOOPDEV ]; then
Binary file not shown.
@@ -0,0 +1,21 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
img=${1:-"exfat.img"}
truncate -s 32M $img
mkfs.exfat $img >> /dev/null
dump_info=$(dump.exfat $img)
clu_heap_off=$(echo "${dump_info}" | grep "Cluster Heap Offset (sector offset):" | cut -d ':' -f 2)
upcase_clu=$(echo "${dump_info}" | grep "Upcase table start cluster:" | cut -d ':' -f 2)
clu_size=$(echo "${dump_info}" | grep "Cluster size:" | cut -d ':' -f 2)
sector_size=$(echo "${dump_info}" | grep "Bytes per Sector:" | cut -d ':' -f 2)
upcase_entry_off=$(echo "${dump_info}" | grep "Upcase table entry position:" | cut -d ':' -f 2)
# Make TableChecksum field corrupted
checksum_off=$((${upcase_entry_off}+4))
echo "$(printf "%x" $checksum_off):0xff" | xxd -r - $img
# Make upcase table corrupted
upcase_off=$(((${upcase_clu} - 2) * ${clu_size} + ${clu_heap_off} * ${sector_size}))
echo "$(printf "%x" $upcase_off):0x7F" | xxd -r - $img
+13
View File
@@ -0,0 +1,13 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
img=${1:-"exfat.img"}
truncate -s 32M $img
mkfs.exfat $img >> /dev/null
dump_info=$(dump.exfat $img)
upcase_entry_off=$(echo "${dump_info}" | grep "Upcase table entry position:" | cut -d ':' -f 2)
# Make FirstCluster field corrupted
start_clu_off=$((${upcase_entry_off}+20))
echo "$(printf "%x" $start_clu_off):0x00" | xxd -r - $img
+15
View File
@@ -0,0 +1,15 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
img=${1:-"exfat.img"}
truncate -s 32M $img
mkfs.exfat $img >> /dev/null
dump_info=$(dump.exfat $img)
upcase_entry_off=$(echo "${dump_info}" | grep "Upcase table entry position:" | cut -d ':' -f 2)
size_off=$((${upcase_entry_off}+24))
# Make DataLength field corrupted
echo "$(printf "%x" $size_off):0x00" | xxd -r - $img
echo "$(printf "%x" $(($size_off + 1))):0x00" | xxd -r - $img
+13
View File
@@ -0,0 +1,13 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
img=${1:-"exfat.img"}
truncate -s 32M $img
mkfs.exfat $img >> /dev/null
dump_info=$(dump.exfat $img)
upcase_entry_off=$(echo "${dump_info}" | grep "Upcase table entry position:" | cut -d ':' -f 2)
# Make EntryType field corrupted
echo "$(printf "%x" $upcase_entry_off):0x7F" | xxd -r - $img
+2 -21
View File
@@ -56,7 +56,6 @@ int main(int argc, char *argv[])
int flags = 0;
char label_input[VOLUME_LABEL_BUFFER_SIZE];
struct exfat *exfat = NULL;
struct pbr *bs;
init_user_input(&ui);
@@ -133,30 +132,12 @@ int main(int argc, char *argv[])
goto close_fd_out;
}
ret = read_boot_sect(&bd, &bs);
if (ret)
goto close_fd_out;
exfat = exfat_alloc_exfat(&bd, bs);
exfat = exfat_alloc_exfat(&bd, NULL, NULL);
if (!exfat) {
ret = -ENOMEM;
goto close_fd_out;
}
exfat->root = exfat_alloc_inode(ATTR_SUBDIR);
if (!exfat->root) {
ret = -ENOMEM;
goto close_fd_out;
}
exfat->root->first_clus = le32_to_cpu(exfat->bs->bsx.root_cluster);
if (exfat_root_clus_count(exfat)) {
exfat_err("failed to follow the cluster chain of root\n");
exfat_free_inode(exfat->root);
ret = -EINVAL;
goto close_fd_out;
}
if (flags == EXFAT_GET_VOLUME_LABEL)
ret = exfat_read_volume_label(exfat);
else if (flags == EXFAT_SET_VOLUME_LABEL)
@@ -171,5 +152,5 @@ close_fd_out:
if (exfat)
exfat_free_exfat(exfat);
out:
return ret;
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}