/[pearpc]/src/io/prom/fs/hfs/medium.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/io/prom/fs/hfs/medium.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 6588 byte(s)
import upstream CVS
1 /*
2 * libhfs - library for reading and writing Macintosh HFS volumes
3 * Copyright (C) 1996-1998 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21 # ifdef HAVE_CONFIG_H
22 # include "config.h"
23 # endif
24
25 # include <stdlib.h>
26 # include <string.h>
27 # include <errno.h>
28
29 # include "libhfs.h"
30 # include "block.h"
31 # include "low.h"
32 # include "medium.h"
33
34 /* Driver Descriptor Record Routines ======================================= */
35
36 /*
37 * NAME: medium->zeroddr()
38 * DESCRIPTION: write a new/empty driver descriptor record
39 */
40 int m_zeroddr(hfsvol *vol)
41 {
42 Block0 ddr;
43 int i;
44
45 ASSERT(vol->pnum == 0 && vol->vlen != 0);
46
47 ddr.sbSig = HFS_DDR_SIGWORD;
48 ddr.sbBlkSize = HFS_BLOCKSZ;
49 ddr.sbBlkCount = vol->vlen;
50
51 ddr.sbDevType = 0;
52 ddr.sbDevId = 0;
53 ddr.sbData = 0;
54
55 ddr.sbDrvrCount = 0;
56
57 ddr.ddBlock = 0;
58 ddr.ddSize = 0;
59 ddr.ddType = 0;
60
61 for (i = 0; i < 243; ++i)
62 ddr.ddPad[i] = 0;
63
64 return l_putddr(vol, &ddr);
65 }
66
67 /* Partition Map Routines ================================================== */
68
69 /*
70 * NAME: medium->zeropm()
71 * DESCRIPTION: write new/empty partition map
72 */
73 int m_zeropm(hfsvol *vol, unsigned int maxparts)
74 {
75 ApplePartition map;
76 unsigned int i;
77
78 ASSERT(vol->pnum == 0 && vol->vlen != 0);
79
80 if (maxparts < 2)
81 ERROR(EINVAL, "must allow at least 2 partitions");
82
83 /* first entry: partition map itself */
84
85 map.pmSig = HFS_PM_SIGWORD;
86 map.pmSigPad = 0;
87 map.pmMapBlkCnt = 2;
88
89 map.pmPyPartStart = 1;
90 map.pmPartBlkCnt = maxparts;
91
92 strcpy((char *) map.pmPartName, "Apple");
93 strcpy((char *) map.pmParType, "Apple_partition_map");
94
95 map.pmLgDataStart = 0;
96 map.pmDataCnt = map.pmPartBlkCnt;
97
98 map.pmPartStatus = 0;
99
100 map.pmLgBootStart = 0;
101 map.pmBootSize = 0;
102 map.pmBootAddr = 0;
103 map.pmBootAddr2 = 0;
104 map.pmBootEntry = 0;
105 map.pmBootEntry2 = 0;
106 map.pmBootCksum = 0;
107
108 strcpy((char *) map.pmProcessor, "");
109
110 for (i = 0; i < 188; ++i)
111 map.pmPad[i] = 0;
112
113 if (l_putpmentry(vol, &map, 1) == -1)
114 goto fail;
115
116 /* second entry: rest of medium */
117
118 map.pmPyPartStart = 1 + maxparts;
119 map.pmPartBlkCnt = vol->vlen - 1 - maxparts;
120
121 strcpy((char *) map.pmPartName, "Extra");
122 strcpy((char *) map.pmParType, "Apple_Free");
123
124 map.pmDataCnt = map.pmPartBlkCnt;
125
126 if (l_putpmentry(vol, &map, 2) == -1)
127 goto fail;
128
129 /* zero rest of partition map's partition */
130
131 if (maxparts > 2)
132 {
133 block b;
134
135 memset(&b, 0, sizeof(b));
136
137 for (i = 3; i <= maxparts; ++i)
138 {
139 if (b_writepb(vol, i, &b, 1) == -1)
140 goto fail;
141 }
142 }
143
144 return 0;
145
146 fail:
147 return -1;
148 }
149
150 /*
151 * NAME: medium->findpmentry()
152 * DESCRIPTION: locate a partition map entry
153 */
154 int m_findpmentry(hfsvol *vol, const char *type,
155 ApplePartition *map, unsigned long *start)
156 {
157 unsigned long bnum;
158 int found = 0;
159
160 if (start && *start > 0)
161 {
162 bnum = *start;
163
164 /* if (bnum++ >= (unsigned long) map->pmMapBlkCnt) {
165 ERROR(EINVAL, "partition not found");
166 }*/
167 }
168 else
169 bnum = 1;
170
171 while (1)
172 {
173 if (l_getpmentry(vol, map, bnum) == -1)
174 {
175 found = -1;
176 goto fail;
177 }
178
179 if (map->pmSig != HFS_PM_SIGWORD)
180 {
181 found = -1;
182
183 if (map->pmSig == HFS_PM_SIGWORD_OLD)
184 ERROR(EINVAL, "old partition map format not supported");
185 else
186 ERROR(EINVAL, "invalid partition map");
187 }
188
189 if (strcmp((char *) map->pmParType, type) == 0)
190 {
191 found = 1;
192 goto done;
193 }
194
195 if (bnum++ >= (unsigned long) map->pmMapBlkCnt) {
196 ERROR(EINVAL, "partition not found");
197 }
198 }
199
200 done:
201 /* if (start)
202 *start = bnum;*/
203
204 fail:
205 return found;
206 }
207
208 /*
209 * NAME: medium->mkpart()
210 * DESCRIPTION: create a new partition from available free space
211 */
212 int m_mkpart(hfsvol *vol,
213 const char *name, const char *type, unsigned long len)
214 {
215 ApplePartition map;
216 unsigned int nparts, maxparts;
217 unsigned long bnum, start, remain;
218 int found;
219
220 if (strlen(name) > 32 ||
221 strlen(type) > 32)
222 ERROR(EINVAL, "partition name/type can each be at most 32 chars");
223
224 if (len == 0)
225 ERROR(EINVAL, "partition length must be > 0");
226
227 found = m_findpmentry(vol, "Apple_partition_map", &map, 0);
228 if (found == -1)
229 goto fail;
230
231 if (! found)
232 ERROR(EIO, "cannot find partition map's partition");
233
234 nparts = map.pmMapBlkCnt;
235 maxparts = map.pmPartBlkCnt;
236
237 bnum = 0;
238 do
239 {
240 found = m_findpmentry(vol, "Apple_Free", &map, &bnum);
241 if (found == -1)
242 goto fail;
243
244 if (! found)
245 ERROR(ENOSPC, "no available partitions");
246 }
247 while (len > (unsigned long) map.pmPartBlkCnt);
248
249 start = (unsigned long) map.pmPyPartStart + len;
250 remain = (unsigned long) map.pmPartBlkCnt - len;
251
252 if (remain && nparts >= maxparts)
253 ERROR(EINVAL, "must allocate all blocks in free space");
254
255 map.pmPartBlkCnt = len;
256
257 strcpy((char *) map.pmPartName, name);
258 strcpy((char *) map.pmParType, type);
259
260 map.pmLgDataStart = 0;
261 map.pmDataCnt = len;
262
263 map.pmPartStatus = 0;
264
265 if (l_putpmentry(vol, &map, bnum) == -1)
266 goto fail;
267
268 if (remain)
269 {
270 map.pmPyPartStart = start;
271 map.pmPartBlkCnt = remain;
272
273 strcpy((char *) map.pmPartName, "Extra");
274 strcpy((char *) map.pmParType, "Apple_Free");
275
276 map.pmDataCnt = remain;
277
278 if (l_putpmentry(vol, &map, ++nparts) == -1)
279 goto fail;
280
281 for (bnum = 1; bnum <= nparts; ++bnum)
282 {
283 if (l_getpmentry(vol, &map, bnum) == -1)
284 goto fail;
285
286 map.pmMapBlkCnt = nparts;
287
288 if (l_putpmentry(vol, &map, bnum) == -1)
289 goto fail;
290 }
291 }
292
293 return 0;
294
295 fail:
296 return -1;
297 }
298
299 /* Boot Blocks Routines ==================================================== */
300
301 /*
302 * NAME: medium->zerobb()
303 * DESCRIPTION: write new/empty volume boot blocks
304 */
305 int m_zerobb(hfsvol *vol)
306 {
307 block b;
308
309 memset(&b, 0, sizeof(b));
310
311 if (b_writelb(vol, 0, &b) == -1 ||
312 b_writelb(vol, 1, &b) == -1)
313 goto fail;
314
315 return 0;
316
317 fail:
318 return -1;
319 }

  ViewVC Help
Powered by ViewVC 1.1.26