Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / pdisk / hfs_misc.c
blob3189f367564b38851daa092534ae85d1204a09a9
1 //
2 // hfs_misc.c - hfs routines
3 //
4 // Written by Eryk Vershen
5 //
7 /*
8 * Copyright 2000 by Eryk Vershen
9 */
11 // for *printf()
12 #include <stdio.h>
14 // for malloc(), calloc() & free()
15 #ifndef __linux__
16 #include <stdlib.h>
17 #else
18 #include <malloc.h>
19 #endif
21 // for strncpy() & strcmp()
22 #include <string.h>
23 // for O_RDONLY & O_RDWR
24 #include <fcntl.h>
25 // for errno
26 #include <errno.h>
28 #include "hfs_misc.h"
29 #include "partition_map.h"
30 #include "convert.h"
31 #include "errors.h"
35 // Defines
37 #define MDB_OFFSET 2
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))
45 // Types
47 typedef long long u64;
49 typedef struct ExtDescriptor { // extent descriptor
50 u16 xdrStABN; // first allocation block
51 u16 xdrNumABlks; // number of allocation blocks
52 } ext_descriptor;
54 typedef struct ExtDataRec {
55 ext_descriptor ed[3]; // extent data record
56 } ext_data_rec;
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
87 #ifdef notdef
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
91 #else
92 u16 drEmbedSigWord; // type of embedded volume
93 ext_descriptor drEmbedExtent; // embedded volume extent
94 #endif
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 {
105 u32 startBlock;
106 u32 blockCount;
107 } HFSPlusExtentDescriptor;
109 typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[ 8];
111 typedef struct HFSPlusForkData {
112 u64 logicalSize;
113 u32 clumpSize;
114 u32 totalBlocks;
115 HFSPlusExtentRecord extents;
116 } HFSPlusForkData;
118 struct HFSPlusVolumeHeader {
119 u16 signature;
120 u16 version;
121 u32 attributes;
122 u32 lastMountedVersion;
123 u32 reserved;
124 u32 createDate;
125 u32 modifyDate;
126 u32 backupDate;
127 u32 checkedDate;
128 u32 fileCount;
129 u32 folderCount;
130 u32 blockSize;
131 u32 totalBlocks;
132 u32 freeBlocks;
133 u32 nextAllocation;
134 u32 rsrcClumpSize;
135 u32 dataClumpSize;
136 HFSCatalogNodeID nextCatalogID;
137 u32 writeCount;
138 u64 encodingsBitmap;
139 u8 finderInfo[ 32];
140 HFSPlusForkData allocationFile;
141 HFSPlusForkData extentsFile;
142 HFSPlusForkData catalogFile;
143 HFSPlusForkData attributesFile;
144 HFSPlusForkData startupFile;
145 } HFSPlusVolumeHeader;
149 // Global Constants
154 // Global Variables
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);
166 // Routines
169 embeded_offset(struct mdb_record *mdb, u32 sector)
171 u32 e_offset;
173 e_offset = mdb->drAlBlSt + mdb->drEmbedExtent.xdrStABN * (mdb->drAlBlkSiz / 512);
175 return e_offset + sector;
179 char *
180 get_HFS_name(partition_map *entry, int *kind)
182 DPME *data;
183 struct mdb_record *mdb;
184 //struct HFSPlusVolumeHeader *mdb2;
185 char *name = NULL;
186 int len;
188 *kind = kHFS_not;
190 mdb = (struct mdb_record *) malloc(PBLOCK_SIZE);
191 if (mdb == NULL) {
192 error(errno, "can't allocate memory for MDB");
193 return NULL;
196 data = entry->data;
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);
200 goto not_hfs;
202 if (mdb->drSigWord == HFS_PLUS_SIG) {
203 // pure HFS Plus
204 // printf("%lu HFS Plus\n", entry->disk_address);
205 *kind = kHFS_plus;
206 } else if (mdb->drSigWord != HFS_SIG) {
207 // not HFS !!!
208 printf("%lu not HFS\n", entry->disk_address);
209 *kind = kHFS_not;
210 } else if (mdb->drEmbedSigWord != HFS_PLUS_SIG) {
211 // HFS
212 // printf("%lu HFS\n", entry->disk_address);
213 *kind = kHFS_std;
214 len = mdb->drVN[0];
215 name = (char *) malloc(len+1);
216 strncpy(name, &mdb->drVN[1], len);
217 name[len] = 0;
218 } else {
219 // embedded HFS plus
220 // printf("%lu embedded HFS Plus\n", entry->disk_address);
221 *kind = kHFS_embed;
222 len = mdb->drVN[0];
223 name = (char *) malloc(len+1);
224 strncpy(name, &mdb->drVN[1], len);
225 name[len] = 0;
228 not_hfs:
229 free(mdb);
230 return name;
233 // really need a function to read block n from partition m
236 read_partition_block(partition_map *entry, unsigned long num, char *buf)
238 DPME *data;
239 partition_map_header * map;
240 u32 base;
241 u64 offset;
243 map = entry->the_map;
244 data = entry->data;
245 base = data->dpme_pblock_start;
247 if (num >= data->dpme_pblocks) {
248 return 0;
250 offset = ((long long) base) * map->logical_block + num * 512;
252 return read_media(map->m, offset, 512, (void *)buf);