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 #include <assert.h>
28 #include <err.h>
29 #include <errno.h>
30 #include <stdbool.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "fstyp.h"
37
38 /*
39 * https://developer.apple.com/library/archive/technotes/tn/tn1150.html
40 */
41
42 #define VOL_HDR_OFF 1024
43
44 typedef uint32_t hfsp_cat_nodeid;
45
46 typedef struct hfsp_ext_desc {
47 uint32_t ex_startBlock;
48 uint32_t ex_blockCount;
49 } hfsp_ext_desc;
50
51 typedef struct hfsp_fork_data {
52 uint64_t fd_logicalSz;
53 uint32_t fd_clumpSz;
54 uint32_t fd_totalBlocks;
55 hfsp_ext_desc fd_extents[8];
56 } hfsp_fork_data;
57
58 struct hfsp_vol_hdr {
59 char hp_signature[2];
60 uint16_t hp_version;
61 uint32_t hp_attributes;
62 uint32_t hp_lastMounted;
63 uint32_t hp_journalInfoBlock;
64
65 /* Creation / etc dates. */
66 uint32_t hp_create;
67 uint32_t hp_modify;
68 uint32_t hp_backup;
69 uint32_t hp_checked;
70
71 /* Stats */
72 uint32_t hp_files;
73 uint32_t hp_folders;
74
75 /* Parameters */
76 uint32_t hp_blockSize;
77 uint32_t hp_totalBlocks;
78 uint32_t hp_freeBlocks;
79
80 uint32_t hp_nextAlloc;
81 uint32_t hp_rsrcClumpSz;
82 uint32_t hp_dataClumpSz;
83
84 hfsp_cat_nodeid hp_nextCatID;
85
86 uint32_t hp_writeCount;
87 uint64_t hp_encodingsBM;
88
89 uint32_t hp_finderInfo[8];
90
91 hfsp_fork_data hp_allocationFile;
92 hfsp_fork_data hp_extentsFile;
93 hfsp_fork_data hp_catalogFile;
94 hfsp_fork_data hp_attributesFile;
95 hfsp_fork_data hp_startupFile;
96 };
97 _Static_assert(sizeof(struct hfsp_vol_hdr) == 512, "");
98
99 int
fstyp_hfsp(FILE * fp,char * label,size_t size)100 fstyp_hfsp(FILE *fp, char *label, size_t size)
101 {
102 struct hfsp_vol_hdr *hdr;
103 int retval;
104
105 retval = 1;
106 hdr = read_buf(fp, VOL_HDR_OFF, sizeof(*hdr));
107 if (hdr == NULL)
108 goto fail;
109
110 if ((strncmp(hdr->hp_signature, "H+", 2) != 0 || hdr->hp_version != 4)
111 &&
112 (strncmp(hdr->hp_signature, "HX", 2) != 0 || hdr->hp_version != 5))
113 goto fail;
114
115 /* This is an HFS+ volume. */
116 retval = 0;
117
118 /* No label support yet. */
119 (void)size;
120 (void)label;
121
122 fail:
123 free(hdr);
124 return (retval);
125 }
126