2 // hfs_misc.c - hfs routines
4 // Written by Eryk Vershen
8 * Copyright 2000 by Eryk Vershen
14 // for malloc(), calloc() & free()
21 // for strncpy() & strcmp()
23 // for O_RDONLY & O_RDWR
29 #include "partition_map.h"
38 #define HFS_SIG 0x4244 /* i.e 'BD' */
39 #define HFS_PLUS_SIG 0x482B /* i.e 'H+' */
41 #define get_align_long(x) (*(u32*)(x))
47 typedef long long u64
;
49 typedef struct ExtDescriptor
{ // extent descriptor
50 u16 xdrStABN
; // first allocation block
51 u16 xdrNumABlks
; // number of allocation blocks
54 typedef struct ExtDataRec
{
55 ext_descriptor ed
[3]; // extent data record
59 * The crazy "u16 x[2]" stuff here is to get around the fact
60 * that I can't convince the Mac compiler to align on 32 bit
61 * quantities on 16 bit boundaries...
63 struct mdb_record
{ // master directory block
64 u16 drSigWord
; // volume signature
65 u16 drCrDate
[2]; // date and time of volume creation
66 u16 drLsMod
[2]; // date and time of last modification
67 u16 drAtrb
; // volume attributes
68 u16 drNmFls
; // number of files in root directory
69 u16 drVBMSt
; // first block of volume bitmap
70 u16 drAllocPtr
; // start of next allocation search
71 u16 drNmAlBlks
; // number of allocation blocks in volume
72 u32 drAlBlkSiz
; // size (in bytes) of allocation blocks
73 u32 drClpSiz
; // default clump size
74 u16 drAlBlSt
; // first allocation block in volume
75 u16 drNxtCNID
[2]; // next unused catalog node ID
76 u16 drFreeBks
; // number of unused allocation blocks
77 char drVN
[28]; // volume name
78 u16 drVolBkUp
[2]; // date and time of last backup
79 u16 drVSeqNum
; // volume backup sequence number
80 u16 drWrCnt
[2]; // volume write count
81 u16 drXTClpSiz
[2]; // clump size for extents overflow file
82 u16 drCTClpSiz
[2]; // clump size for catalog file
83 u16 drNmRtDirs
; // number of directories in root directory
84 u32 drFilCnt
; // number of files in volume
85 u32 drDirCnt
; // number of directories in volume
86 u32 drFndrInfo
[8]; // information used by the Finder
88 u16 drVCSize
; // size (in blocks) of volume cache
89 u16 drVBMCSize
; // size (in blocks) of volume bitmap cache
90 u16 drCtlCSize
; // size (in blocks) of common volume cache
92 u16 drEmbedSigWord
; // type of embedded volume
93 ext_descriptor drEmbedExtent
; // embedded volume extent
95 u16 drXTFlSize
[2]; // size of extents overflow file
96 ext_data_rec drXTExtRec
; // extent record for extents overflow file
97 u16 drCTFlSize
[2]; // size of catalog file
98 ext_data_rec drCTExtRec
; // extent record for catalog file
102 typedef u32 HFSCatalogNodeID
;
104 typedef struct HFSPlusExtentDescriptor
{
107 } HFSPlusExtentDescriptor
;
109 typedef HFSPlusExtentDescriptor HFSPlusExtentRecord
[ 8];
111 typedef struct HFSPlusForkData
{
115 HFSPlusExtentRecord extents
;
118 struct HFSPlusVolumeHeader
{
122 u32 lastMountedVersion
;
136 HFSCatalogNodeID nextCatalogID
;
140 HFSPlusForkData allocationFile
;
141 HFSPlusForkData extentsFile
;
142 HFSPlusForkData catalogFile
;
143 HFSPlusForkData attributesFile
;
144 HFSPlusForkData startupFile
;
145 } HFSPlusVolumeHeader
;
159 // Forward declarations
161 u32
embeded_offset(struct mdb_record
*mdb
, u32 sector
);
162 int read_partition_block(partition_map
*entry
, unsigned long num
, char *buf
);
169 embeded_offset(struct mdb_record
*mdb
, u32 sector
)
173 e_offset
= mdb
->drAlBlSt
+ mdb
->drEmbedExtent
.xdrStABN
* (mdb
->drAlBlkSiz
/ 512);
175 return e_offset
+ sector
;
180 get_HFS_name(partition_map
*entry
, int *kind
)
183 struct mdb_record
*mdb
;
184 //struct HFSPlusVolumeHeader *mdb2;
190 mdb
= (struct mdb_record
*) malloc(PBLOCK_SIZE
);
192 error(errno
, "can't allocate memory for MDB");
197 if (strcmp(data
->dpme_type
, kHFSType
) == 0) {
198 if (read_partition_block(entry
, 2, (char *)mdb
) == 0) {
199 error(-1, "Can't read block %d from partition %d", 2, entry
->disk_address
);
202 if (mdb
->drSigWord
== HFS_PLUS_SIG
) {
204 // printf("%lu HFS Plus\n", entry->disk_address);
206 } else if (mdb
->drSigWord
!= HFS_SIG
) {
208 printf("%lu not HFS\n", entry
->disk_address
);
210 } else if (mdb
->drEmbedSigWord
!= HFS_PLUS_SIG
) {
212 // printf("%lu HFS\n", entry->disk_address);
215 name
= (char *) malloc(len
+1);
216 strncpy(name
, &mdb
->drVN
[1], len
);
220 // printf("%lu embedded HFS Plus\n", entry->disk_address);
223 name
= (char *) malloc(len
+1);
224 strncpy(name
, &mdb
->drVN
[1], len
);
233 // really need a function to read block n from partition m
236 read_partition_block(partition_map
*entry
, unsigned long num
, char *buf
)
239 partition_map_header
* map
;
243 map
= entry
->the_map
;
245 base
= data
->dpme_pblock_start
;
247 if (num
>= data
->dpme_pblocks
) {
250 offset
= ((long long) base
) * map
->logical_block
+ num
* 512;
252 return read_media(map
->m
, offset
, 512, (void *)buf
);