New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / workbench / c / Partition / main.c
blob51b2981c90d93818d0771574b99330c85eca054a
1 /*
2 Copyright © 2003-2006, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <utility/tagitem.h>
7 #include <libraries/partition.h>
8 #include <devices/trackdisk.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <proto/partition.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
17 #define DEBUG 0
18 #include <aros/debug.h>
20 #include "args.h"
23 /*** Prototypes *************************************************************/
24 struct PartitionHandle *CreateRootTable(CONST_STRPTR device, LONG unit);
25 struct PartitionHandle *CreateMBRPartition(struct PartitionHandle *parent, ULONG lowcyl, ULONG highcyl);
26 struct PartitionHandle *CreateRDBPartition(struct PartitionHandle *parent, ULONG lowcyl, ULONG highcyl, CONST_STRPTR name, BOOL bootable);
28 /*** Functions **************************************************************/
29 int main(void)
31 struct PartitionHandle *root = NULL;
32 TEXT choice = 'N';
33 CONST_STRPTR device;
34 ULONG unit;
36 if (!ReadArguments())
38 PrintFault(IoErr(), NULL);
39 return RETURN_FAIL;
42 device = (CONST_STRPTR) ARG(DEVICE);
43 unit = *(LONG *)ARG(UNIT);
45 D(bug("[C:Partition] Using %s, unit %d\n", device, unit));
47 if (ARG(QUIET) && !ARG(FORCE))
49 PutStr("ERROR: Cannot specify QUIET without FORCE.\n");
50 return RETURN_FAIL;
53 if (!ARG(FORCE))
55 Printf("About to partition %s unit %d.\n", device, unit);
56 Printf("This will DESTROY ALL DATA on the drive!\n");
57 Printf("Are you sure? (y/N)"); Flush(Output());
59 Read(Input(), &choice, 1);
61 else
63 choice = 'y';
66 if (choice != 'y' && choice != 'Y') return RETURN_OK;
68 if (!ARG(QUIET))
70 Printf("Partitioning drive...");
71 Flush(Output());
74 D(bug("[C:Partition] Partitioning drive...\n"));
76 if ((root = CreateRootTable(device, unit)) != NULL)
78 CONST ULONG TABLESIZE = 5 * 1024 * 1024;
79 CONST ULONG DH0SIZE = 1 * 1024 * 1024;
80 struct DriveGeometry rootDG = {0};
81 ULONG rootSize; /* Size in kB */
83 GetPartitionAttrsTags(root, PT_GEOMETRY, (IPTR) &rootDG, TAG_DONE);
84 rootSize = (rootDG.dg_TotalSectors / 1024) * rootDG.dg_SectorSize;
86 /* See if the partition is 5 GB or larger */
87 if (rootSize >= TABLESIZE)
89 /*
90 Only use the first 5 GB, first creating a 1 GB system
91 partition (DH0) and then a 4 GB user partition (DH1).
94 struct PartitionHandle *mbrp = NULL, /* MBR partition */
95 *rdbp0 = NULL, /* First RDB partition */
96 *rdbp1 = NULL; /* Second RDB partition */
98 ULONG cylSize = rootSize / rootDG.dg_Cylinders,
99 mbrhighcyl = (TABLESIZE / cylSize) - 1,
100 rdbp0highcyl = (DH0SIZE / cylSize) - 1,
101 rdbp1lowcyl = rdbp0highcyl + 1,
102 rdbp1highcyl;
104 /* Create a partition in the MBR table */
105 mbrp = CreateMBRPartition(root, 0, mbrhighcyl);
107 /* Create RDB partition table inside MBR partition */
108 if (CreatePartitionTable(mbrp, PHPTT_RDB) != 0)
110 PutStr("*** ERROR: Creating partition table failed. Aborting.\n");
111 return RETURN_FAIL; /* FIXME: take care of allocated resources... */
114 /* Create a partition in the RDB table */
115 rdbp0 = CreateRDBPartition(mbrp, 0, rdbp0highcyl, "DH0", TRUE); // FIXME: error check
116 rdbp1highcyl = mbrhighcyl - mbrp->de.de_LowCyl;
117 rdbp1 = CreateRDBPartition(mbrp, rdbp1lowcyl, rdbp1highcyl, "DH1", FALSE); // FIXME: error check
119 /* Save to disk and deallocate */
120 WritePartitionTable(mbrp);
121 ClosePartitionTable(mbrp);
123 else
126 Use the entire partition.
129 struct PartitionHandle *mbrp = NULL, /* MBR partition */
130 *rdbp = NULL; /* RDB partition */
132 /* Create a partition in the MBR table */
133 mbrp = CreateMBRPartition(root, 0, 0);
135 /* Create RDB partition table inside MBR partition */
136 if (CreatePartitionTable(mbrp, PHPTT_RDB) != 0)
138 PutStr("*** ERROR: Creating partition table failed. Aborting.\n");
139 return RETURN_FAIL; /* FIXME: take care of allocated resources... */
142 /* Create a partition in the RDB table */
143 rdbp = CreateRDBPartition(mbrp, 0, 0, "DH0", TRUE); // FIXME: error check
145 /* Save to disk and deallocate */
146 WritePartitionTable(mbrp);
147 ClosePartitionTable(mbrp);
150 /* Save to disk and deallocate */
151 WritePartitionTable(root);
152 ClosePartitionTable(root);
153 CloseRootPartition(root);
156 if (!ARG(QUIET)) Printf("done\n");
158 return RETURN_OK;
161 struct PartitionHandle *CreateRootTable(CONST_STRPTR device, LONG unit)
163 struct PartitionHandle *root;
165 if ((root = OpenRootPartition(device, unit)) != NULL)
167 /* Destroy the existing partitiontable, if any exists */
168 DestroyPartitionTable(root);
170 /* Create a root MBR partition table */
171 if (CreatePartitionTable(root, PHPTT_MBR) != 0)
173 PutStr("*** ERROR: Creating partition table failed.\n");
174 CloseRootPartition(root);
175 root = NULL;
178 else
180 PutStr("*** Could not open root partition!\n");
183 return root;
186 struct PartitionHandle *CreateMBRPartition
188 struct PartitionHandle *parent, ULONG lowcyl, ULONG highcyl
191 struct DriveGeometry parentDG = {0};
192 struct DosEnvec parentDE = {0},
193 partitionDE = {0};
194 struct PartitionType type = {{0x30}, 1}; /* AROS RDB */
195 struct PartitionHandle *partition;
197 GetPartitionAttrsTags
199 parent,
201 PT_DOSENVEC, (IPTR) &parentDE,
202 PT_GEOMETRY, (IPTR) &parentDG,
204 TAG_DONE
207 if (lowcyl == 0)
209 ULONG reserved;
211 GetPartitionTableAttrsTags
213 parent, PTT_RESERVED, (IPTR) &reserved, TAG_DONE
216 lowcyl = (reserved - 1) /
217 (parentDG.dg_Heads * parentDG.dg_TrackSectors) + 1;
220 if (highcyl == 0)
222 highcyl = parentDE.de_HighCyl;
225 CopyMem(&parentDE, &partitionDE, sizeof(struct DosEnvec));
227 partitionDE.de_SizeBlock = parentDG.dg_SectorSize >> 2;
228 partitionDE.de_Reserved = 2;
229 partitionDE.de_HighCyl = highcyl;
230 partitionDE.de_LowCyl = lowcyl;
232 partition = AddPartitionTags
234 parent,
236 PT_DOSENVEC, (IPTR) &partitionDE,
237 PT_TYPE, (IPTR) &type,
238 PT_POSITION, 0,
239 PT_ACTIVE, TRUE,
241 TAG_DONE
244 return partition;
247 struct PartitionHandle *CreateRDBPartition
249 struct PartitionHandle *parent, ULONG lowcyl, ULONG highcyl,
250 CONST_STRPTR name, BOOL bootable
253 struct DriveGeometry parentDG = {0};
254 struct DosEnvec parentDE = {0},
255 partitionDE = {0};
256 struct PartitionType type = {"DOS\3", 4};
257 struct PartitionHandle *partition;
259 GetPartitionAttrsTags
261 parent,
263 PT_DOSENVEC, (IPTR) &parentDE,
264 PT_GEOMETRY, (IPTR) &parentDG,
266 TAG_DONE
269 if (lowcyl == 0)
271 ULONG reserved;
273 GetPartitionTableAttrsTags
275 parent, PTT_RESERVED, (IPTR) &reserved, TAG_DONE
278 lowcyl = (reserved - 1)
279 / (parentDG.dg_Heads * parentDG.dg_TrackSectors) + 1;
282 if (highcyl == 0)
284 highcyl = parentDE.de_HighCyl - parentDE.de_LowCyl;
287 CopyMem(&parentDE, &partitionDE, sizeof(struct DosEnvec));
289 partitionDE.de_SizeBlock = parentDG.dg_SectorSize >> 2;
290 partitionDE.de_Surfaces = parentDG.dg_Heads;
291 partitionDE.de_BlocksPerTrack = parentDG.dg_TrackSectors;
292 partitionDE.de_BufMemType = parentDG.dg_BufMemType;
293 partitionDE.de_TableSize = DE_DOSTYPE;
294 partitionDE.de_Reserved = 2;
295 partitionDE.de_HighCyl = highcyl;
296 partitionDE.de_LowCyl = lowcyl;
297 partitionDE.de_NumBuffers = 100;
298 partitionDE.de_MaxTransfer = 0xFFFFFF;
299 partitionDE.de_Mask = 0xFFFFFFFE;
301 D(bug("[C:Partition] SizeBlock %d\n", partitionDE.de_SizeBlock ));
302 D(bug("[C:Partition] Surfaces %d\n", partitionDE.de_Surfaces));
303 D(bug("[C:Partition] BlocksPerTrack %d\n", partitionDE.de_BlocksPerTrack));
304 D(bug("[C:Partition] BufMemType %d\n", partitionDE.de_BufMemType));
305 D(bug("[C:Partition] TableSize %d\n", partitionDE.de_TableSize));
306 D(bug("[C:Partition] Reserved %d\n", partitionDE.de_Reserved));
307 D(bug("[C:Partition] HighCyl %d\n", partitionDE.de_HighCyl));
308 D(bug("[C:Partition] LowCyl %d\n", partitionDE.de_LowCyl));
310 partition = AddPartitionTags
312 parent,
314 PT_DOSENVEC, (IPTR) &partitionDE,
315 PT_TYPE, (IPTR) &type,
316 PT_NAME, (IPTR) name,
317 PT_BOOTABLE, bootable,
318 PT_AUTOMOUNT, TRUE,
320 TAG_DONE
323 return partition;