xref: /freebsd/usr.sbin/fstyp/hfsplus.c (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
150c59bbbSConrad Meyer /*
250c59bbbSConrad Meyer  * Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org>.  All rights reserved.
350c59bbbSConrad Meyer  *
450c59bbbSConrad Meyer  * Redistribution and use in source and binary forms, with or without
550c59bbbSConrad Meyer  * modification, are permitted provided that the following conditions
650c59bbbSConrad Meyer  * are met:
750c59bbbSConrad Meyer  * 1. Redistributions of source code must retain the above copyright
850c59bbbSConrad Meyer  *    notice, this list of conditions and the following disclaimer.
950c59bbbSConrad Meyer  * 2. Redistributions in binary form must reproduce the above copyright
1050c59bbbSConrad Meyer  *    notice, this list of conditions and the following disclaimer in the
1150c59bbbSConrad Meyer  *    documentation and/or other materials provided with the distribution.
1250c59bbbSConrad Meyer  *
1350c59bbbSConrad Meyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1450c59bbbSConrad Meyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1550c59bbbSConrad Meyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1650c59bbbSConrad Meyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1750c59bbbSConrad Meyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1850c59bbbSConrad Meyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1950c59bbbSConrad Meyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2050c59bbbSConrad Meyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2150c59bbbSConrad Meyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2250c59bbbSConrad Meyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2350c59bbbSConrad Meyer  * SUCH DAMAGE.
2450c59bbbSConrad Meyer  */
2550c59bbbSConrad Meyer 
2650c59bbbSConrad Meyer #include <sys/cdefs.h>
2750c59bbbSConrad Meyer #include <assert.h>
2850c59bbbSConrad Meyer #include <err.h>
2950c59bbbSConrad Meyer #include <errno.h>
3050c59bbbSConrad Meyer #include <stdbool.h>
3150c59bbbSConrad Meyer #include <stdint.h>
3250c59bbbSConrad Meyer #include <stdio.h>
3350c59bbbSConrad Meyer #include <stdlib.h>
3450c59bbbSConrad Meyer #include <string.h>
3550c59bbbSConrad Meyer 
3650c59bbbSConrad Meyer #include "fstyp.h"
3750c59bbbSConrad Meyer 
3850c59bbbSConrad Meyer /*
3950c59bbbSConrad Meyer  * https://developer.apple.com/library/archive/technotes/tn/tn1150.html
4050c59bbbSConrad Meyer  */
4150c59bbbSConrad Meyer 
4250c59bbbSConrad Meyer #define	VOL_HDR_OFF	1024
4350c59bbbSConrad Meyer 
4450c59bbbSConrad Meyer typedef uint32_t hfsp_cat_nodeid;
4550c59bbbSConrad Meyer 
4650c59bbbSConrad Meyer typedef struct hfsp_ext_desc {
4750c59bbbSConrad Meyer 	uint32_t	ex_startBlock;
4850c59bbbSConrad Meyer 	uint32_t	ex_blockCount;
4950c59bbbSConrad Meyer } hfsp_ext_desc;
5050c59bbbSConrad Meyer 
5150c59bbbSConrad Meyer typedef struct hfsp_fork_data {
5250c59bbbSConrad Meyer 	uint64_t	fd_logicalSz;
5350c59bbbSConrad Meyer 	uint32_t	fd_clumpSz;
5450c59bbbSConrad Meyer 	uint32_t	fd_totalBlocks;
5550c59bbbSConrad Meyer 	hfsp_ext_desc	fd_extents[8];
5650c59bbbSConrad Meyer } hfsp_fork_data;
5750c59bbbSConrad Meyer 
5850c59bbbSConrad Meyer struct hfsp_vol_hdr {
5950c59bbbSConrad Meyer 	char		hp_signature[2];
6050c59bbbSConrad Meyer 	uint16_t	hp_version;
6150c59bbbSConrad Meyer 	uint32_t	hp_attributes;
6250c59bbbSConrad Meyer 	uint32_t	hp_lastMounted;
6350c59bbbSConrad Meyer 	uint32_t	hp_journalInfoBlock;
6450c59bbbSConrad Meyer 
6550c59bbbSConrad Meyer 	/* Creation / etc dates. */
6650c59bbbSConrad Meyer 	uint32_t	hp_create;
6750c59bbbSConrad Meyer 	uint32_t	hp_modify;
6850c59bbbSConrad Meyer 	uint32_t	hp_backup;
6950c59bbbSConrad Meyer 	uint32_t	hp_checked;
7050c59bbbSConrad Meyer 
7150c59bbbSConrad Meyer 	/* Stats */
7250c59bbbSConrad Meyer 	uint32_t	hp_files;
7350c59bbbSConrad Meyer 	uint32_t	hp_folders;
7450c59bbbSConrad Meyer 
7550c59bbbSConrad Meyer 	/* Parameters */
7650c59bbbSConrad Meyer 	uint32_t	hp_blockSize;
7750c59bbbSConrad Meyer 	uint32_t	hp_totalBlocks;
7850c59bbbSConrad Meyer 	uint32_t	hp_freeBlocks;
7950c59bbbSConrad Meyer 
8050c59bbbSConrad Meyer 	uint32_t	hp_nextAlloc;
8150c59bbbSConrad Meyer 	uint32_t	hp_rsrcClumpSz;
8250c59bbbSConrad Meyer 	uint32_t	hp_dataClumpSz;
8350c59bbbSConrad Meyer 
8450c59bbbSConrad Meyer 	hfsp_cat_nodeid	hp_nextCatID;
8550c59bbbSConrad Meyer 
8650c59bbbSConrad Meyer 	uint32_t	hp_writeCount;
8750c59bbbSConrad Meyer 	uint64_t	hp_encodingsBM;
8850c59bbbSConrad Meyer 
8950c59bbbSConrad Meyer 	uint32_t	hp_finderInfo[8];
9050c59bbbSConrad Meyer 
9150c59bbbSConrad Meyer 	hfsp_fork_data	hp_allocationFile;
9250c59bbbSConrad Meyer 	hfsp_fork_data	hp_extentsFile;
9350c59bbbSConrad Meyer 	hfsp_fork_data	hp_catalogFile;
9450c59bbbSConrad Meyer 	hfsp_fork_data	hp_attributesFile;
9550c59bbbSConrad Meyer 	hfsp_fork_data	hp_startupFile;
9650c59bbbSConrad Meyer };
9750c59bbbSConrad Meyer _Static_assert(sizeof(struct hfsp_vol_hdr) == 512, "");
9850c59bbbSConrad Meyer 
9950c59bbbSConrad Meyer int
fstyp_hfsp(FILE * fp,char * label,size_t size)10050c59bbbSConrad Meyer fstyp_hfsp(FILE *fp, char *label, size_t size)
10150c59bbbSConrad Meyer {
10250c59bbbSConrad Meyer 	struct hfsp_vol_hdr *hdr;
10350c59bbbSConrad Meyer 	int retval;
10450c59bbbSConrad Meyer 
10550c59bbbSConrad Meyer 	retval = 1;
10650c59bbbSConrad Meyer 	hdr = read_buf(fp, VOL_HDR_OFF, sizeof(*hdr));
10750c59bbbSConrad Meyer 	if (hdr == NULL)
10850c59bbbSConrad Meyer 		goto fail;
10950c59bbbSConrad Meyer 
11050c59bbbSConrad Meyer 	if ((strncmp(hdr->hp_signature, "H+", 2) != 0 || hdr->hp_version != 4)
11150c59bbbSConrad Meyer 	    &&
11250c59bbbSConrad Meyer 	    (strncmp(hdr->hp_signature, "HX", 2) != 0 || hdr->hp_version != 5))
11350c59bbbSConrad Meyer 		goto fail;
11450c59bbbSConrad Meyer 
11550c59bbbSConrad Meyer 	/* This is an HFS+ volume. */
11650c59bbbSConrad Meyer 	retval = 0;
11750c59bbbSConrad Meyer 
11850c59bbbSConrad Meyer 	/* No label support yet. */
119*da0c0e01SPiotr Pawel Stefaniak 	(void)size;
120*da0c0e01SPiotr Pawel Stefaniak 	(void)label;
12150c59bbbSConrad Meyer 
12250c59bbbSConrad Meyer fail:
12350c59bbbSConrad Meyer 	free(hdr);
12450c59bbbSConrad Meyer 	return (retval);
12550c59bbbSConrad Meyer }
126