Coverage Report

Created: 2026-02-22 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/hpfs.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3
 *
4
 * Inspired by libvolume_id by
5
 *     Kay Sievers <kay.sievers@vrfy.org>
6
 *
7
 * This file may be redistributed under the terms of the
8
 * GNU Lesser General Public License.
9
 */
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <unistd.h>
13
#include <string.h>
14
#include <stdint.h>
15
16
#include "superblocks.h"
17
18
struct hpfs_boot_block
19
{
20
  uint8_t   jmp[3];
21
  uint8_t   oem_id[8];
22
  uint8_t   bytes_per_sector[2];
23
  uint8_t   sectors_per_cluster;
24
  uint8_t   n_reserved_sectors[2];
25
  uint8_t   n_fats;
26
  uint8_t   n_rootdir_entries[2];
27
  uint8_t   n_sectors_s[2];
28
  uint8_t   media_byte;
29
  uint16_t  sectors_per_fat;
30
  uint16_t  sectors_per_track;
31
  uint16_t  heads_per_cyl;
32
  uint32_t  n_hidden_sectors;
33
  uint32_t  n_sectors_l;
34
  uint8_t   drive_number;
35
  uint8_t   mbz;
36
  uint8_t   sig_28h;
37
  uint8_t   vol_serno[4];
38
  uint8_t   vol_label[11];
39
  uint8_t   sig_hpfs[8];
40
  uint8_t   pad[448];
41
  uint8_t   magic[2];
42
} __attribute__((packed));
43
44
struct hpfs_super_block
45
{
46
  uint8_t   magic[4];
47
  uint8_t   magic1[4];
48
  uint8_t   version;
49
} __attribute__((packed));
50
51
struct hpfs_spare_super
52
{
53
  uint8_t   magic[4];
54
  uint8_t   magic1[4];
55
} __attribute__((packed));
56
57
58
#define HPFS_SB_OFFSET      0x2000
59
135
#define HPFS_SBSPARE_OFFSET   0x2200
60
61
static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
62
135
{
63
135
  const struct hpfs_super_block *hs;
64
135
  const struct hpfs_spare_super *hss;
65
135
  const struct hpfs_boot_block *hbb;
66
135
  uint8_t version;
67
68
  /* super block */
69
135
  hs = blkid_probe_get_sb(pr, mag, struct hpfs_super_block);
70
135
  if (!hs)
71
0
    return errno ? -errno : 1;
72
135
  version = hs->version;
73
74
  /* spare super block */
75
135
  hss = (struct hpfs_spare_super *)
76
135
      blkid_probe_get_buffer(pr,
77
135
        HPFS_SBSPARE_OFFSET,
78
135
        sizeof(struct hpfs_spare_super));
79
135
  if (!hss)
80
0
    return errno ? -errno : 1;
81
135
  if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
82
121
    return 1;
83
84
  /* boot block (with UUID and LABEL) */
85
14
  hbb = (struct hpfs_boot_block *)
86
14
      blkid_probe_get_buffer(pr,
87
14
        0,
88
14
        sizeof(struct hpfs_boot_block));
89
14
  if (!hbb)
90
0
    return errno ? -errno : 1;
91
14
  if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
92
2
      memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
93
1
      hbb->sig_28h == 0x28) {
94
0
    blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label));
95
0
    blkid_probe_sprintf_uuid(pr,
96
0
        hbb->vol_serno, sizeof(hbb->vol_serno),
97
0
        "%02X%02X-%02X%02X",
98
0
        hbb->vol_serno[3], hbb->vol_serno[2],
99
0
        hbb->vol_serno[1], hbb->vol_serno[0]);
100
0
  }
101
14
  blkid_probe_sprintf_version(pr, "%u", version);
102
14
  blkid_probe_set_fsblocksize(pr, 512);
103
14
  blkid_probe_set_block_size(pr, 512);
104
105
14
  return 0;
106
14
}
107
108
const struct blkid_idinfo hpfs_idinfo =
109
{
110
  .name   = "hpfs",
111
  .usage    = BLKID_USAGE_FILESYSTEM,
112
  .probefunc  = probe_hpfs,
113
  .magics   =
114
  {
115
    {
116
      .magic = "\x49\xe8\x95\xf9",
117
      .len = 4,
118
      .kboff = (HPFS_SB_OFFSET >> 10)
119
    },
120
    { NULL }
121
  }
122
};
123
124