]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/fstyp/hfsplus.c
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / usr.sbin / fstyp / hfsplus.c
1 /*
2  * Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org>.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include <assert.h>
30 #include <err.h>
31 #include <errno.h>
32 #include <stdbool.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "fstyp.h"
39
40 /*
41  * https://developer.apple.com/library/archive/technotes/tn/tn1150.html
42  */
43
44 #define VOL_HDR_OFF     1024
45
46 typedef uint32_t hfsp_cat_nodeid;
47
48 typedef struct hfsp_ext_desc {
49         uint32_t        ex_startBlock;
50         uint32_t        ex_blockCount;
51 } hfsp_ext_desc;
52
53 typedef struct hfsp_fork_data {
54         uint64_t        fd_logicalSz;
55         uint32_t        fd_clumpSz;
56         uint32_t        fd_totalBlocks;
57         hfsp_ext_desc   fd_extents[8];
58 } hfsp_fork_data;
59
60 struct hfsp_vol_hdr {
61         char            hp_signature[2];
62         uint16_t        hp_version;
63         uint32_t        hp_attributes;
64         uint32_t        hp_lastMounted;
65         uint32_t        hp_journalInfoBlock;
66
67         /* Creation / etc dates. */
68         uint32_t        hp_create;
69         uint32_t        hp_modify;
70         uint32_t        hp_backup;
71         uint32_t        hp_checked;
72
73         /* Stats */
74         uint32_t        hp_files;
75         uint32_t        hp_folders;
76
77         /* Parameters */
78         uint32_t        hp_blockSize;
79         uint32_t        hp_totalBlocks;
80         uint32_t        hp_freeBlocks;
81
82         uint32_t        hp_nextAlloc;
83         uint32_t        hp_rsrcClumpSz;
84         uint32_t        hp_dataClumpSz;
85
86         hfsp_cat_nodeid hp_nextCatID;
87
88         uint32_t        hp_writeCount;
89         uint64_t        hp_encodingsBM;
90
91         uint32_t        hp_finderInfo[8];
92
93         hfsp_fork_data  hp_allocationFile;
94         hfsp_fork_data  hp_extentsFile;
95         hfsp_fork_data  hp_catalogFile;
96         hfsp_fork_data  hp_attributesFile;
97         hfsp_fork_data  hp_startupFile;
98 };
99 _Static_assert(sizeof(struct hfsp_vol_hdr) == 512, "");
100
101 int
102 fstyp_hfsp(FILE *fp, char *label, size_t size)
103 {
104         struct hfsp_vol_hdr *hdr;
105         int retval;
106
107         retval = 1;
108         hdr = read_buf(fp, VOL_HDR_OFF, sizeof(*hdr));
109         if (hdr == NULL)
110                 goto fail;
111
112         if ((strncmp(hdr->hp_signature, "H+", 2) != 0 || hdr->hp_version != 4)
113             &&
114             (strncmp(hdr->hp_signature, "HX", 2) != 0 || hdr->hp_version != 5))
115                 goto fail;
116
117         /* This is an HFS+ volume. */
118         retval = 0;
119
120         /* No label support yet. */
121
122 fail:
123         free(hdr);
124         return (retval);
125 }