xref: /freebsd/usr.sbin/fstyp/hfsplus.c (revision 61e21613)
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
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