2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
6 #include <proto/exec.h>
7 #include <proto/gadtools.h>
8 #include <proto/intuition.h>
9 #include <proto/partition.h>
10 #include <proto/alib.h>
12 #include <devices/trackdisk.h>
13 #include <exec/memory.h>
14 #include <utility/tagitem.h>
19 #include "partitions.h"
20 #include "hdtoolbox_support.h"
28 void setPartitionName(struct HDTBPartition
*pnode
)
30 D(bug("[HDToolBox] setPartitionName()\n"));
33 sprintf(pnode
->listnode
.ln
.ln_Name
, "Partition %d", (int)pnode
->pos
);
38 pnode
->listnode
.ln
.ln_Name
,
46 struct HDTBPartition
*newPartition(struct ListNode
*parent
, struct HDTBPartition
*partition
)
48 struct HDTBPartition
*pn
;
50 D(bug("[HDToolBox] newPartition()\n"));
52 pn
= AllocMem(sizeof(struct HDTBPartition
), MEMF_PUBLIC
| MEMF_CLEAR
);
55 pn
->listnode
.ln
.ln_Name
= AllocVec(100, MEMF_PUBLIC
| MEMF_CLEAR
);
56 if (pn
->listnode
.ln
.ln_Name
)
58 if (InitListNode(&pn
->listnode
, parent
))
60 pn
->listnode
.ln
.ln_Type
= LNT_Partition
;
62 D(bug("[HDToolBox] newPartition successful - new partition at %p\n", pn
));
65 FreeVec(pn
->listnode
.ln
.ln_Name
);
67 FreeMem(pn
, sizeof(struct HDTBPartition
));
69 D(bug("[HDToolBox] newPartition failed\n"));
73 void findPartitions(struct ListNode
*parent
, struct HDTBPartition
*partition
)
75 struct PartitionHandle
*ph
;
76 struct HDTBPartition
*pn
;
79 D(bug("[HDToolBox] findPartitions()\n"));
83 ph
= (struct PartitionHandle
*)partition
->ph
->table
->list
.lh_Head
;
85 ph
= (struct PartitionHandle
*)ph
->ln
.ln_Succ
88 pn
= newPartition(parent
, partition
);
89 D(bug("[HDToolBox] - found new partition at %p, created node at %p\n", ph
, pn
));
102 * check if we can read partition type
104 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_TYPE
) & PLAM_READ
)
106 GetPartitionAttrsA(pn
->ph
, PT_TYPE
, &pn
->type
, TAG_DONE
);
107 D(bug("[HDToolBox] - ID valid (%ld)\n", pn
->type
));
113 D(bug("[HDToolBox] - ID invalid\n"));
117 * read partition location
119 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_POSITION
) & PLAM_READ
)
121 GetPartitionAttrsA(pn
->ph
, PT_POSITION
, &pn
->pos
, TAG_DONE
);
122 D(bug("[HDToolBox] - Position valid (%ld)\n", pn
->pos
));
127 D(bug("[HDToolBox] - Position invalid\n"));
131 * read partition name
133 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_NAME
) & PLAM_READ
)
135 GetPartitionAttrsA(pn
->ph
, PT_NAME
, pn
->listnode
.ln
.ln_Name
, TAG_DONE
);
136 D(bug("[HDToolBox] - Name valid (%s)\n", pn
->listnode
.ln
.ln_Name
));
140 setPartitionName(pn
);
141 D(bug("[HDToolBox] - Name generated (%s)\n", pn
->listnode
.ln
.ln_Name
));
145 * check bootable flag
147 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_BOOTABLE
) & PLAM_READ
)
149 GetPartitionAttrsA(pn
->ph
, PT_BOOTABLE
, &flag
, TAG_DONE
);
151 pn
->flags
|= PNF_BOOTABLE
;
152 D(bug("[HDToolBox] - Bootable flag %s\n", flag
? "enabled" : "disabled"));
158 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_AUTOMOUNT
) & PLAM_READ
)
160 GetPartitionAttrsA(pn
->ph
, PT_AUTOMOUNT
, &flag
, TAG_DONE
);
162 pn
->flags
|= PNF_AUTOMOUNT
;
163 D(bug("[HDToolBox] - Automount flag %s\n", flag
? "enabled" : "disabled"));
167 * check if partition is active (MBR-specific)
169 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_ACTIVE
) & PLAM_READ
)
171 GetPartitionAttrsA(pn
->ph
, PT_ACTIVE
, &flag
, TAG_DONE
);
173 pn
->flags
|= PNF_ACTIVE
;
174 D(bug("[HDToolBox] - Active flag %s\n", flag
? "enabled" : "disabled"));
177 if (pn
->root
->table
->max_partitions
)
179 pn
->listnode
.ln
.ln_Pri
=pn
->root
->table
->max_partitions
-1-pn
->pos
;
180 Enqueue(&parent
->list
, &pn
->listnode
.ln
);
183 AddTail(&parent
->list
, &pn
->listnode
.ln
);
184 if (findPartitionTable(pn
))
186 findPartitions(&pn
->listnode
, pn
);
187 pn
->listnode
.flags
|= LNF_Listable
;
191 D(bug("[HDToolBox] findPartitions() successful\n"));
194 void freePartitionNode(struct HDTBPartition
*node
)
196 D(bug("[HDToolBox] freePartitionNode(%p)\n", node
));
200 D(bug("[HDToolBox] Freeing sub-table %p\n", node
->table
));
201 freePartitionList(&node
->listnode
.list
);
202 freePartitionTable(node
);
204 UninitListNode(&node
->listnode
);
205 FreeVec(node
->listnode
.ln
.ln_Name
);
206 FreeMem(node
, sizeof(struct HDTBPartition
));
209 void freePartitionList(struct List
*list
)
211 struct HDTBPartition
*node
;
212 struct HDTBPartition
*next
;
214 D(bug("[HDToolBox] freePartitionList(%p)\n", list
));
216 node
= (struct HDTBPartition
*)list
->lh_Head
;
217 while (node
->listnode
.ln
.ln_Succ
)
219 next
= (struct HDTBPartition
*)node
->listnode
.ln
.ln_Succ
;
220 if (node
->listnode
.ln
.ln_Type
!= LNT_Parent
)
222 Remove(&node
->listnode
.ln
);
223 freePartitionNode(node
);
229 BOOL
validValue(struct HDTBPartition
*table
, struct HDTBPartition
*current
, ULONG value
)
231 struct HDTBPartition
*pn
;
234 D(bug("[HDToolBox] validValue()\n"));
236 if (value
<table
->table
->reserved
)
238 D(bug("[HDToolBox] - value (%ld) < table->reserved (%ld) -> bad\n", value
, table
->table
->reserved
));
241 spc
= table
->dg
.dg_Heads
*table
->dg
.dg_TrackSectors
;
242 if (value
>=(table
->dg
.dg_Cylinders
*spc
))
244 D(bug("[HDToolBox] - value (%ld) >= table->dg.dg_Cylinders*spc (%ld) -> bad\n", value
, table
->dg
.dg_Cylinders
*spc
));
249 pn
= (struct HDTBPartition
*)table
->listnode
.list
.lh_Head
;
250 pn
->listnode
.ln
.ln_Succ
;
251 pn
= (struct HDTBPartition
*)pn
->listnode
.ln
.ln_Succ
)
253 D(bug("[HDToolBox] - List %p / Partition %p / Next %p / Current %p\n", &table
->listnode
, pn
, pn
->listnode
.ln
.ln_Succ
, current
));
254 D(bug("[HDToolBox] - Partition Type: %lx\n", pn
->type
));
256 /* don't analyze PARENT, don't analyze ROOT */
257 if (pn
->listnode
.ln
.ln_Type
!= LNT_Partition
)
260 /* don't check currently processed partition */
263 spc
= pn
->de
.de_Surfaces
*pn
->de
.de_BlocksPerTrack
;
265 (value
>= (pn
->de
.de_LowCyl
*spc
)) &&
266 (value
< (((pn
->de
.de_HighCyl
+1)*spc
)-1))
269 D(bug("[HDToolBox] - value (%ld) within bounds <%ld; %ld) -> bad\n", value
, pn
->de
.de_LowCyl
* spc
, (pn
->de
.de_HighCyl
+1)*spc
-1));
275 D(bug("[HDToolBox] - value (%ld) good\n", value
));
279 struct HDTBPartition
*addPartition(struct HDTBPartition
*table
, struct DosEnvec
*de
)
281 struct HDTBPartition
*partition
;
282 struct HDTBPartition
*pn
;
283 struct TableTypeNode
*ttn
;
284 ULONG leadin
= 0, blocks_per_cyl
;
286 D(bug("[HDToolBox] addPartition()\n"));
288 partition
= newPartition(&table
->listnode
, table
);
291 if (table
->table
->max_partitions
)
293 /* find first free position */
295 pn
= (struct HDTBPartition
*)table
->listnode
.list
.lh_Head
;
296 while (pn
->listnode
.ln
.ln_Succ
)
298 if (pn
->listnode
.ln
.ln_Type
!= LNT_Parent
)
302 partition
->pos
= count
;
307 pn
= (struct HDTBPartition
*)pn
->listnode
.ln
.ln_Succ
;
309 if (pn
->listnode
.ln
.ln_Succ
== NULL
)
310 partition
->pos
= count
;
311 partition
->listnode
.ln
.ln_Pri
= table
->table
->max_partitions
-1-partition
->pos
;
312 Enqueue(&table
->listnode
.list
, &partition
->listnode
.ln
);
315 AddTail(&table
->listnode
.list
, &partition
->listnode
.ln
);
317 de
->de_TableSize
= DE_DOSTYPE
;
318 de
->de_MaxTransfer
= 0xFFFFFF;
319 de
->de_Mask
= 0xFFFFFFFE;
321 de
->de_BufMemType
= MEMF_PUBLIC
;
323 CopyMem(de
, &partition
->de
, sizeof(struct DosEnvec
));
324 ttn
= findTableTypeNode(table
->table
->type
);
325 CopyMem(&ttn
->defaulttype
, &partition
->type
, sizeof(struct PartitionType
));
326 if (getAttrInfo(table
->table
->pattrlist
, PTA_NAME
) & PLAM_WRITE
)
327 strcpy(partition
->listnode
.ln
.ln_Name
, "DH0");
329 setPartitionName(partition
);
331 GetPartitionTableAttrsTags(table
->ph
, PTT_MAXLEADIN
, &leadin
, TAG_DONE
);
333 blocks_per_cyl
= de
->de_Surfaces
* de
->de_BlocksPerTrack
;
334 de
->de_LowCyl
+= (leadin
+ blocks_per_cyl
- 1) / blocks_per_cyl
;
335 D(bug("[HDToolBox] addPartition() Prepared Envec:\n"));
336 D(bug("[HDToolBox] - LeadIn : %ld\n", leadin
));
337 D(bug("[HDToolBox] - SizeBlock : %ld\n", de
->de_SizeBlock
));
338 D(bug("[HDToolBox] - SecOrg : %ld\n", de
->de_SecOrg
));
339 D(bug("[HDToolBox] - Surfaces : %ld\n", de
->de_Surfaces
));
340 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de
->de_SectorPerBlock
));
341 D(bug("[HDToolBox] - Reserved : %ld\n", de
->de_Reserved
));
342 D(bug("[HDToolBox] - LowCyl : %ld\n", de
->de_LowCyl
));
343 D(bug("[HDToolBox] - HighCyl : %ld\n", de
->de_HighCyl
));
344 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de
->de_BlocksPerTrack
));
345 D(bug("[HDToolBox] - BootBlocks : %ld\n", de
->de_BootBlocks
));
347 partition
->ph
= AddPartitionTags(table
->ph
,
349 PT_TYPE
, &partition
->type
,
350 PT_NAME
, partition
->listnode
.ln
.ln_Name
,
351 PT_POSITION
, partition
->pos
,
355 /* We did not set GEOMETRY so partitionlib did it. Update geometry and DOS type in local DOSEnvec */
356 GetPartitionAttrsTags(partition
->ph
, PT_GEOMETRY
, &partition
->dg
,
357 PT_DOSENVEC
, &partition
->de
,
361 D(bug("[HDToolBox] addPartition() Real Envec:\n"));
362 D(bug("[HDToolBox] - SizeBlock : %ld\n", de
->de_SizeBlock
));
363 D(bug("[HDToolBox] - SecOrg : %ld\n", de
->de_SecOrg
));
364 D(bug("[HDToolBox] - Surfaces : %ld\n", de
->de_Surfaces
));
365 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de
->de_SectorPerBlock
));
366 D(bug("[HDToolBox] - Reserved : %ld\n", de
->de_Reserved
));
367 D(bug("[HDToolBox] - LowCyl : %ld\n", de
->de_LowCyl
));
368 D(bug("[HDToolBox] - HighCyl : %ld\n", de
->de_HighCyl
));
369 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de
->de_BlocksPerTrack
));
370 D(bug("[HDToolBox] - BootBlocks : %ld\n", de
->de_BootBlocks
));
371 D(bug("[HDToolBox] addPartition() successful\n"));
375 D(bug("[HDToolBox] addPartition() failed to add partition\n"));
376 freePartitionNode(partition
);
378 D(bug("[HDToolBox] addPartition() failed\n"));