--- /dev/null
+/*
+ * Copyright (C) 1999, 2001 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct hpfs_boot_block
+{
+ uint8_t jmp[3];
+ uint8_t oem_id[8];
+ uint8_t bytes_per_sector[2];
+ uint8_t sectors_per_cluster;
+ uint8_t n_reserved_sectors[2];
+ uint8_t n_fats;
+ uint8_t n_rootdir_entries[2];
+ uint8_t n_sectors_s[2];
+ uint8_t media_byte;
+ uint16_t sectors_per_fat;
+ uint16_t sectors_per_track;
+ uint16_t heads_per_cyl;
+ uint32_t n_hidden_sectors;
+ uint32_t n_sectors_l;
+ uint8_t drive_number;
+ uint8_t mbz;
+ uint8_t sig_28h;
+ uint8_t vol_serno[4];
+ uint8_t vol_label[11];
+ uint8_t sig_hpfs[8];
+ uint8_t pad[448];
+ uint8_t magic[2];
+};
+
+struct hpfs_super
+{
+ uint8_t magic[4];
+ uint8_t magic1[4];
+ uint8_t version;
+};
+
+struct hpfs_spare_super
+{
+ uint8_t magic[4];
+ uint8_t magic1[4];
+};
+
+
+#define HPFS_SB_OFFSET 0x2000
+#define HPFS_SBSPARE_OFFSET 0x2200
+
+static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct hpfs_super *hs;
+ struct hpfs_spare_super *hss;
+ struct hpfs_boot_block *hbb;
+ uint8_t version;
+
+ /* super block */
+ hs = blkid_probe_get_sb(pr, mag, struct hpfs_super);
+ if (!hs)
+ return -1;
+ version = hs->version;
+
+ /* spare super block */
+ hss = (struct hpfs_spare_super *)
+ blkid_probe_get_buffer(pr,
+ HPFS_SBSPARE_OFFSET,
+ sizeof(struct hpfs_spare_super));
+ if (!hss)
+ return -1;
+ if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
+ return -1;
+
+ /* boot block (with UUID and LABEL) */
+ hbb = (struct hpfs_boot_block *)
+ blkid_probe_get_buffer(pr,
+ 0,
+ sizeof(struct hpfs_boot_block));
+ if (!hbb)
+ return -1;
+ if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
+ memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
+ hbb->sig_28h == 0x28) {
+ blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label));
+ blkid_probe_sprintf_uuid(pr,
+ hbb->vol_serno, sizeof(hbb->vol_serno),
+ "%02X%02X-%02X%02X",
+ hbb->vol_serno[3], hbb->vol_serno[2],
+ hbb->vol_serno[1], hbb->vol_serno[0]);
+ }
+ blkid_probe_sprintf_version(pr, "%u", version);
+
+ return 0;
+}
+
+const struct blkid_idinfo hpfs_idinfo =
+{
+ .name = "hpfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_hpfs,
+ .magics =
+ {
+ {
+ .magic = "\x49\xe8\x95\xf9",
+ .len = 4,
+ .kboff = (HPFS_SB_OFFSET >> 10)
+ },
+ { NULL }
+ }
+};
+
+