(root)/
util-linux-2.39/
libblkid/
src/
superblocks/
hpfs.c
       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  #define HPFS_SBSPARE_OFFSET		0x2200
      60  
      61  static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
      62  {
      63  	struct hpfs_super_block *hs;
      64  	struct hpfs_spare_super *hss;
      65  	struct hpfs_boot_block *hbb;
      66  	uint8_t version;
      67  
      68  	/* super block */
      69  	hs = blkid_probe_get_sb(pr, mag, struct hpfs_super_block);
      70  	if (!hs)
      71  		return errno ? -errno : 1;
      72  	version = hs->version;
      73  
      74  	/* spare super block */
      75  	hss = (struct hpfs_spare_super *)
      76  			blkid_probe_get_buffer(pr,
      77  				HPFS_SBSPARE_OFFSET,
      78  				sizeof(struct hpfs_spare_super));
      79  	if (!hss)
      80  		return errno ? -errno : 1;
      81  	if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
      82  		return 1;
      83  
      84  	/* boot block (with UUID and LABEL) */
      85  	hbb = (struct hpfs_boot_block *)
      86  			blkid_probe_get_buffer(pr,
      87  				0,
      88  				sizeof(struct hpfs_boot_block));
      89  	if (!hbb)
      90  		return errno ? -errno : 1;
      91  	if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
      92  	    memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
      93  	    hbb->sig_28h == 0x28) {
      94  		blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label));
      95  		blkid_probe_sprintf_uuid(pr,
      96  				hbb->vol_serno, sizeof(hbb->vol_serno),
      97  				"%02X%02X-%02X%02X",
      98  				hbb->vol_serno[3], hbb->vol_serno[2],
      99  				hbb->vol_serno[1], hbb->vol_serno[0]);
     100  	}
     101  	blkid_probe_sprintf_version(pr, "%u", version);
     102  	blkid_probe_set_fsblocksize(pr, 512);
     103  	blkid_probe_set_block_size(pr, 512);
     104  
     105  	return 0;
     106  }
     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