]> git.sven.stormbind.net Git - sven/exfat-utils.git/blobdiff - mkfs/rootdir.c
Merge tag 'upstream/1.1.0'
[sven/exfat-utils.git] / mkfs / rootdir.c
index 547ca3b3927ee60834961b83350e793722442c34..4b6446dbf7a4a6556ed1778413c1d79b070fa601 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-2014  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 <string.h>
+#include "rootdir.h"
+#include "uct.h"
+#include "cbm.h"
+#include "uctc.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(struct exfat_dev* dev, off_t base)
+static void init_label_entry(struct exfat_entry_label* label_entry)
 {
 {
+       memset(label_entry, 0, sizeof(struct exfat_entry_label));
+       label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID;
+
+       if (utf16_length(get_volume_label()) == 0)
+               return;
+
+       memcpy(label_entry->name, get_volume_label(),
+                       EXFAT_ENAME_MAX * sizeof(le16_t));
+       label_entry->length = utf16_length(get_volume_label());
+       label_entry->type |= EXFAT_ENTRY_VALID;
+}
+
+static void init_bitmap_entry(struct exfat_entry_bitmap* bitmap_entry)
+{
+       memset(bitmap_entry, 0, sizeof(struct exfat_entry_bitmap));
+       bitmap_entry->type = EXFAT_ENTRY_BITMAP;
+       bitmap_entry->start_cluster = cpu_to_le32(EXFAT_FIRST_DATA_CLUSTER);
+       bitmap_entry->size = cpu_to_le64(cbm.get_size());
+}
+
+static void init_upcase_entry(struct exfat_entry_upcase* upcase_entry)
+{
+       size_t i;
+       uint32_t sum = 0;
+
+       for (i = 0; i < sizeof(upcase_table); i++)
+               sum = ((sum << 31) | (sum >> 1)) + upcase_table[i];
+
+       memset(upcase_entry, 0, sizeof(struct exfat_entry_upcase));
+       upcase_entry->type = EXFAT_ENTRY_UPCASE;
+       upcase_entry->checksum = cpu_to_le32(sum);
+       upcase_entry->start_cluster = cpu_to_le32(
+                       (get_position(&uct) - get_position(&cbm)) / get_cluster_size() +
+                       EXFAT_FIRST_DATA_CLUSTER);
+       upcase_entry->size = cpu_to_le64(sizeof(upcase_table));
+}
+
+static int rootdir_write(struct exfat_dev* dev)
+{
+       struct exfat_entry_label label_entry;
+       struct exfat_entry_bitmap bitmap_entry;
+       struct exfat_entry_upcase upcase_entry;
+
+       init_label_entry(&label_entry);
+       init_bitmap_entry(&bitmap_entry);
+       init_upcase_entry(&upcase_entry);
+
        if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
        if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
        if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
        if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
        if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
        if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0)
                return 1;
-       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,
+};