Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/fdisk.tproj/part.c

1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * 2008-05-24:
25 * Tamas Kosarszky: changed caption for partition type 0x07
26 * and added caption for type 0xEE.
27 */
28/*
29 * Copyright (c) 1997 Tobias Weingartner
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by Tobias Weingartner.
43 * 4. The name of the author may not be used to endorse or promote products
44 * derived from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57
58#include <err.h>
59#include <util.h>
60#include <stdio.h>
61#include <string.h>
62#include <unistd.h>
63#include <sys/fcntl.h>
64#include <sys/types.h>
65#include <sys/stat.h>
66#include <machine/param.h>
67#include "disk.h"
68#include "misc.h"
69#include "mbr.h"
70
71
72static const struct part_type {
73inttype;
74charsname[14];
75char*lname;
76} part_types[] = {
77{ 0x00, "unused ", "unused"},
78{ 0x01, "DOS FAT-12 ", "Primary DOS with 12 bit FAT"},
79{ 0x02, "XENIX / ", "XENIX / filesystem"},
80{ 0x03, "XENIX /usr ", "XENIX /usr filesystem"},
81{ 0x04, "DOS FAT-16 ", "Primary DOS with 16 bit FAT"},
82{ 0x05, "Extended DOS", "Extended DOS"},
83{ 0x06, "DOS > 32MB ", "Primary 'big' DOS (> 32MB)"},
84{ 0x07, "NTFS ", "Windows NT NTFS"},
85{ 0x08, "AIX fs ", "AIX filesystem"},
86{ 0x09, "AIX/Coherent", "AIX boot partition or Coherent"},
87{ 0x0A, "OS/2 Bootmgr", "OS/2 Boot Manager or OPUS"},
88{ 0x0B, "Win95 FAT-32", "Primary Win95 w/ 32-bit FAT"},
89{ 0x0C, "Win95 FAT32L", "Primary Win95 w/ 32-bit FAT LBA-mapped"},
90{ 0x0E, "DOS FAT-16 ", "Primary DOS w/ 16-bit FAT, CHS-mapped"},
91{ 0x0F, "Extended LBA", "Extended DOS LBA-mapped"},
92{ 0x10, "OPUS ", "OPUS"},
93{ 0x11, "OS/2 hidden ", "OS/2 BM: hidden DOS 12-bit FAT"},
94{ 0x12, "Compaq Diag.", "Compaq Diagnostics"},
95{ 0x14, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug"},
96{ 0x16, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT >=32M"},
97{ 0x17, "OS/2 hidden ", "OS/2 BM: hidden IFS"},
98{ 0x18, "AST swap ", "AST Windows swapfile"},
99{ 0x19, "Willowtech ", "Willowtech Photon coS"},
100{ 0x20, "Willowsoft ", "Willowsoft OFS1"},
101{ 0x24, "NEC DOS ", "NEC DOS"},
102{ 0x38, "Theos ", "Theos"},
103{ 0x39, "Plan 9 ","Plan 9"},
104{ 0x40, "VENIX 286 ", "VENIX 286 or LynxOS"},
105{ 0x41, "Lin/Minux DR", "Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot"},
106{ 0x42, "LinuxSwap DR", "SFS or Linux swap (sharing disk with DRDOS)"},
107{ 0x43, "Linux DR ", "Linux native (sharing disk with DRDOS)"},
108{ 0x4D, "QNX 4.2 Pri ", "QNX 4.2 Primary"},
109{ 0x4E, "QNX 4.2 Sec ", "QNX 4.2 Secondary"},
110{ 0x4F, "QNX 4.2 Ter ", "QNX 4.2 Tertiary"},
111{ 0x50, "DM ", "DM (disk manager)"},
112{ 0x51, "DM ", "DM6 Aux1 (or Novell)"},
113{ 0x52, "CP/M or SysV", "CP/M or Microport SysV/AT"},
114{ 0x53, "DM ", "DM6 Aux3"},
115{ 0x54, "Ontrack ", "Ontrack"},
116{ 0x55, "EZ-Drive ", "EZ-Drive (disk manager)"},
117{ 0x56, "Golden Bow ", "Golden Bow (disk manager)"},
118{ 0x5C, "Priam ", "Priam Edisk (disk manager)"},
119{ 0x61, "SpeedStor ", "SpeedStor"},
120{ 0x63, "ISC, HURD, *", "ISC, System V/386, GNU HURD or Mach"},
121{ 0x64, "Netware 2.xx", "Novell Netware 2.xx"},
122{ 0x65, "Netware 3.xx", "Novell Netware 3.xx"},
123{ 0x66, "Netware 386 ", "Novell 386 Netware"},
124{ 0x67, "Novell ", "Novell"},
125{ 0x68, "Novell ", "Novell"},
126{ 0x69, "Novell ", "Novell"},
127{ 0x70, "DiskSecure ", "DiskSecure Multi-Boot"},
128{ 0x75, "PCIX ", "PCIX"},
129{ 0x80, "Minix (old) ", "Minix 1.1 ... 1.4a"},
130{ 0x81, "Minix (new) ", "Minix 1.4b ... 1.5.10"},
131{ 0x82, "Linux swap ", "Linux swap"},
132{ 0x83, "Linux files*", "Linux filesystem"},
133{ 0x93, "Amoeba file*", "Amoeba filesystem"},
134{ 0x94, "Amoeba BBT ", "Amoeba bad block table"},
135{ 0x84, "OS/2 hidden ", "OS/2 hidden C: drive"},
136{ 0x85, "Linux ext. ", "Linux extended"},
137{ 0x86, "NT FAT VS ", "NT FAT volume set"},
138{ 0x87, "NTFS VS ", "NTFS volume set or HPFS mirrored"},
139{ 0x93, "Amoeba FS ", "Amoeba filesystem"},
140{ 0x94, "Amoeba BBT ", "Amoeba bad block table"},
141{ 0x99, "Mylex ", "Mylex EISA SCSI"},
142{ 0x9F, "BSDI ", "BSDI BSD/OS"},
143{ 0xA0, "NotebookSave", "Phoenix NoteBIOS save-to-disk"},
144{ 0xA5, "FreeBSD ","FreeBSD"},
145{ 0xA6, "OpenBSD ", "OpenBSD"},
146{ 0xA7, "NEXTSTEP ", "NEXTSTEP"},
147{ 0xA8, "Darwin UFS ","Darwin UFS partition"},
148{ 0xA9, "NetBSD ","NetBSD"},
149{ 0xAB, "Darwin Boot ","Darwin boot partition"},
150{ 0xAF, "HFS+ ","Darwin HFS+ partition"},
151{ 0xB7, "BSDI filesy*", "BSDI BSD/386 filesystem"},
152{ 0xB8, "BSDI swap ", "BSDI BSD/386 swap"},
153{ 0xC0, "CTOS ", "CTOS"},
154{ 0xC1, "DRDOSs FAT12", "DRDOS/sec (FAT-12)"},
155{ 0xC4, "DRDOSs < 32M", "DRDOS/sec (FAT-16, < 32M)"},
156{ 0xC6, "DRDOSs >=32M", "DRDOS/sec (FAT-16, >= 32M)"},
157{ 0xC7, "HPFS Disbled", "Syrinx (Cyrnix?) or HPFS disabled"},
158{ 0xDB, "CPM/C.DOS/C*", "Concurrent CPM or C.DOS or CTOS"},
159{ 0xE1, "SpeedStor ", "DOS access or SpeedStor 12-bit FAT extended partition"},
160{ 0xE3, "SpeedStor ", "DOS R/O or SpeedStor or Storage Dimensions"},
161{ 0xE4, "SpeedStor ", "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
162{ 0xEB, "BeOS/i386 ", "BeOS for Intel"},
163{ 0xEE, "GPT ", "GPT protective partition"},
164{ 0xF1, "SpeedStor ", "SpeedStor or Storage Dimensions"},
165{ 0xF2, "DOS 3.3+ Sec", "DOS 3.3+ Secondary"},
166{ 0xF4, "SpeedStor ", "SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML"},
167{ 0xFF, "Xenix BBT ", "Xenix Bad Block Table"},
168};
169
170void
171PRT_printall()
172{
173int i, idrows;
174
175 idrows = ((sizeof(part_types)/sizeof(struct part_type))+3)/4;
176
177printf("Choose from the following Partition id values:\n");
178for (i = 0; i < idrows; i++) {
179printf("%02X %s %02X %s %02X %s"
180 , part_types[i ].type, part_types[i ].sname
181 , part_types[i+idrows ].type, part_types[i+idrows ].sname
182 , part_types[i+idrows*2].type, part_types[i+idrows*2].sname
183 );
184 if ((i+idrows*3) < (sizeof(part_types)/sizeof(struct part_type))) {
185 printf(" %02X %s\n"
186 , part_types[i+idrows*3].type, part_types[i+idrows*3].sname );
187 }
188else
189 printf( "\n" );
190}
191}
192
193const char *
194PRT_ascii_id(id)
195int id;
196{
197static char unknown[] = "<Unknown ID>";
198int i;
199
200for (i = 0; i < sizeof(part_types)/sizeof(struct part_type); i++) {
201if (part_types[i].type == id)
202return (part_types[i].sname);
203}
204
205return (unknown);
206}
207
208void
209PRT_parse(disk, prt, offset, reloff, partn, pn)
210disk_t *disk;
211void *prt;
212off_t offset;
213off_t reloff;
214prt_t *partn;
215int pn;
216{
217unsigned char *p = prt;
218off_t off;
219
220partn->flag = *p++;
221partn->shead = *p++;
222
223partn->ssect = (*p) & 0x3F;
224partn->scyl = ((*p << 2) & 0xFF00) | (*(p+1));
225p += 2;
226
227partn->id = *p++;
228partn->ehead = *p++;
229partn->esect = (*p) & 0x3F;
230partn->ecyl = ((*p << 2) & 0xFF00) | (*(p+1));
231p += 2;
232
233if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
234off = reloff;
235else
236off = offset;
237
238partn->bs = getlong(p) + off;
239partn->ns = getlong(p+4);
240
241
242/* Zero out entry if not used */
243 if (partn->id == DOSPTYP_UNUSED ) {
244 memset(partn, 0, sizeof(*partn));
245 }
246}
247
248int
249PRT_check_chs(partn)
250prt_t *partn;
251{
252if ( (partn->shead > 255) ||
253(partn->ssect >63) ||
254(partn->scyl > 1023) ||
255(partn->ehead >255) ||
256(partn->esect >63) ||
257(partn->ecyl > 1023) )
258{
259return 0;
260}
261return 1;
262}
263void
264PRT_make(partn, offset, reloff, prt)
265prt_t *partn;
266off_t offset;
267off_t reloff;
268void *prt;
269{
270unsigned char *p = prt;
271prt_t tmp;
272off_t off;
273
274tmp.shead = partn->shead;
275tmp.ssect = partn->ssect;
276tmp.scyl = (partn->scyl > 1023)? 1023: partn->scyl;
277tmp.ehead = partn->ehead;
278tmp.esect = partn->esect;
279tmp.ecyl = (partn->ecyl > 1023)? 1023: partn->ecyl;
280if (!PRT_check_chs(partn) && PRT_check_chs(&tmp)) {
281partn->shead = tmp.shead;
282partn->ssect = tmp.ssect;
283partn->scyl = tmp.scyl;
284partn->ehead = tmp.ehead;
285partn->esect = tmp.esect;
286partn->ecyl = tmp.ecyl;
287printf("Cylinder values are modified to fit in CHS.\n");
288}
289if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
290off = reloff;
291else
292off = offset;
293
294if (PRT_check_chs(partn)) {
295*p++ = partn->flag & 0xFF;
296
297*p++ = partn->shead & 0xFF;
298*p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
299*p++ = partn->scyl & 0xFF;
300
301*p++ = partn->id & 0xFF;
302
303*p++ = partn->ehead & 0xFF;
304*p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
305*p++ = partn->ecyl & 0xFF;
306} else {
307/* should this really keep flag, id and set others to 0xff? */
308*p++ = partn->flag & 0xFF;
309*p++ = 0xFF;
310*p++ = 0xFF;
311*p++ = 0xFF;
312*p++ = partn->id & 0xFF;
313*p++ = 0xFF;
314*p++ = 0xFF;
315*p++ = 0xFF;
316printf("Warning CHS values out of bounds only saving LBA values\n");
317}
318
319putlong(p, partn->bs - off);
320putlong(p+4, partn->ns);
321}
322
323void
324PRT_print(num, partn)
325int num;
326prt_t *partn;
327{
328
329if (partn == NULL) {
330printf(" Starting Ending\n");
331printf(" #: id cyl hd sec - cyl hd sec [ start - size]\n");
332printf("------------------------------------------------------------------------\n");
333} else {
334printf("%c%1d: %.2X %4d %3d %3d - %4d %3d %3d [%10d - %10d] %s\n",
335(partn->flag == 0x80)?'*':' ',
336num + 1, partn->id,
337partn->scyl, partn->shead, partn->ssect,
338partn->ecyl, partn->ehead, partn->esect,
339partn->bs, partn->ns,
340PRT_ascii_id(partn->id));
341}
342}
343
344void
345PRT_fix_BN(disk, part, pn)
346disk_t *disk;
347prt_t *part;
348int pn;
349{
350int spt, tpc, spc;
351int start = 0;
352int end = 0;
353
354/* Zero out entry if not used */
355if (part->id == DOSPTYP_UNUSED ) {
356memset(part, 0, sizeof(*part));
357return;
358}
359
360/* Disk metrics */
361spt = disk->real->sectors;
362tpc = disk->real->heads;
363spc = spt * tpc;
364
365start += part->scyl * spc;
366start += part->shead * spt;
367start += part->ssect - 1;
368
369end += part->ecyl * spc;
370end += part->ehead * spt;
371end += part->esect - 1;
372
373/* XXX - Should handle this... */
374if (start > end)
375warn("Start of partition #%d after end!", pn);
376
377part->bs = start;
378part->ns = (end - start) + 1;
379}
380
381void
382PRT_fix_CHS(disk, part, pn)
383disk_t *disk;
384prt_t *part;
385int pn;
386{
387 int spt, tpc, spc;
388 int start;
389int cyl, head, sect;
390
391/* Zero out entry if not used */
392if (part->id == DOSPTYP_UNUSED ) {
393memset(part, 0, sizeof(*part));
394return;
395}
396
397/* Disk metrics */
398spt = disk->real->sectors;
399tpc = disk->real->heads;
400spc = spt * tpc;
401
402start = part->bs;
403
404if(start <= spt) {
405 /* Figure out "real" starting CHS values */
406 cyl = (start / spc); start -= (cyl * spc);
407 head = (start / spt); start -= (head * spt);
408 sect = (start + 1);
409} else {
410 cyl = 1023;
411 head = 254;
412 sect = 63;
413}
414
415part->scyl = cyl;
416part->shead = head;
417part->ssect = sect;
418
419/* use fake geometry to trigger LBA mode */
420
421cyl = 1023;
422head = 254;
423sect = 63;
424
425part->ecyl = cyl;
426part->ehead = head;
427part->esect = sect;
428}
429
430

Archive Download this file

Revision: HEAD