]> git.sven.stormbind.net Git - sven/exfat-utils.git/blobdiff - mkfs/rootdir.c
New upstream version 1.2.6
[sven/exfat-utils.git] / mkfs / rootdir.c
index 4a1a36180b6d3bf7fed4b58e644bcfb18ec879c5..a8cc834139f73f5871e0a406d0c1d948e251f7d4 100644 (file)
@@ -2,11 +2,12 @@
        rootdir.c (09.11.10)
        Root directory creation code.
 
        rootdir.c (09.11.10)
        Root directory creation code.
 
-       Copyright (C) 2009, 2010  Andrew Nayenko
+       Free exFAT implementation.
+       Copyright (C) 2011-2017  Andrew Nayenko
 
 
-       This program is free software: you can redistribute it and/or modify
+       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
        it under the terms of the GNU General Public License as published by
-       the Free Software Foundation, either version 3 of the License, or
+       the Free Software Foundation, either version 2 of the License, or
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
-       You should have received a copy of the GNU General Public License
-       along with this program.  If not, see <http://www.gnu.org/licenses/>.
+       You should have received a copy of the GNU General Public License along
+       with this program; if not, write to the Free Software Foundation, Inc.,
+       51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 */
 
-#include <unistd.h>
-#include <errno.h>
-#include "mkexfat.h"
+#include "rootdir.h"
+#include "uct.h"
+#include "cbm.h"
+#include "uctc.h"
+#include <string.h>
 
 
-off_t rootdir_alignment(void)
+static off_t rootdir_alignment(void)
 {
 {
-       return CLUSTER_SIZE(sb);
+       return get_cluster_size();
 }
 
 }
 
-off_t rootdir_size(void)
+static off_t rootdir_size(void)
 {
 {
-       return CLUSTER_SIZE(sb);
+       return get_cluster_size();
 }
 
 }
 
-int rootdir_write(off_t base, int fd)
+static void init_label_entry(struct exfat_entry_label* label_entry)
 {
 {
-       if (write(fd, &label_entry, sizeof(struct exfat_entry)) == -1)
+       memset(label_entry, 0, sizeof(struct exfat_entry_label));
+       label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID;
+
+       if (utf16_length(get_volume_label()) == 0)
+               return;
+
+       memcpy(label_entry->name, get_volume_label(),
+                       EXFAT_ENAME_MAX * sizeof(le16_t));
+       label_entry->length = utf16_length(get_volume_label());
+       label_entry->type |= EXFAT_ENTRY_VALID;
+}
+
+static void init_bitmap_entry(struct exfat_entry_bitmap* bitmap_entry)
+{
+       memset(bitmap_entry, 0, sizeof(struct exfat_entry_bitmap));
+       bitmap_entry->type = EXFAT_ENTRY_BITMAP;
+       bitmap_entry->start_cluster = cpu_to_le32(EXFAT_FIRST_DATA_CLUSTER);
+       bitmap_entry->size = cpu_to_le64(cbm.get_size());
+}
+
+static void init_upcase_entry(struct exfat_entry_upcase* upcase_entry)
+{
+       size_t i;
+       uint32_t sum = 0;
+
+       for (i = 0; i < sizeof(upcase_table); i++)
+               sum = ((sum << 31) | (sum >> 1)) + upcase_table[i];
+
+       memset(upcase_entry, 0, sizeof(struct exfat_entry_upcase));
+       upcase_entry->type = EXFAT_ENTRY_UPCASE;
+       upcase_entry->checksum = cpu_to_le32(sum);
+       upcase_entry->start_cluster = cpu_to_le32(
+                       (get_position(&uct) - get_position(&cbm)) / get_cluster_size() +
+                       EXFAT_FIRST_DATA_CLUSTER);
+       upcase_entry->size = cpu_to_le64(sizeof(upcase_table));
+}
+
+static int rootdir_write(struct exfat_dev* dev)
+{
+       struct exfat_entry_label label_entry;
+       struct exfat_entry_bitmap bitmap_entry;
+       struct exfat_entry_upcase upcase_entry;
+
+       init_label_entry(&label_entry);
+       init_bitmap_entry(&bitmap_entry);
+       init_upcase_entry(&upcase_entry);
+
+       if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
                return 1;
-       if (write(fd, &bitmap_entry, sizeof(struct exfat_entry)) == -1)
+       if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
                return 1;
-       if (write(fd, &upcase_entry, sizeof(struct exfat_entry)) == -1)
+       if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
                return 1;
-       /* No need to write EOD entry because the whole rootdir cluster was
-          erased by erase_device(). */
-       sb.rootdir_cluster = cpu_to_le32(OFFSET_TO_CLUSTER(base));
        return 0;
 }
        return 0;
 }
+
+const struct fs_object rootdir =
+{
+       .get_alignment = rootdir_alignment,
+       .get_size = rootdir_size,
+       .write = rootdir_write,
+};