Fixed a few warnings.
[tangerine.git] / workbench / libs / partition / partitionrdb.c
blobf9d44abd6aead010287af38783110aaaef519679
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 */
7 #define RDB_WRITE 1
9 #include <proto/exec.h>
10 #include <proto/partition.h>
12 #include <devices/hardblocks.h>
13 #include <exec/memory.h>
14 #include <exec/types.h>
15 #include <libraries/partition.h>
17 #include "partition_support.h"
18 #include "platform.h"
20 #ifndef DEBUG
21 #define DEBUG 1
22 #endif
23 #include "debug.h"
25 #include <string.h>
27 struct RDBData {
28 struct RigidDiskBlock rdb;
29 UBYTE rdbblock; /* the block rdb was read from */
30 struct List badblocklist;
31 struct List fsheaderlist;
34 struct BadBlockNode {
35 struct Node ln;
36 struct BadBlockBlock bbb;
39 struct FileSysNode {
40 struct Node ln;
41 struct FileSysHeaderBlock fhb;
42 struct LoadSegBlock *filesystem; /* the FS in LSEG blocks */
43 ULONG fsblocks; /* nr of LSEG blocks for FS */
46 static ULONG calcChkSum(ULONG *ptr, ULONG size)
48 ULONG i;
49 ULONG sum=0;
51 for (i=0;i<size;i++)
53 sum += AROS_BE2LONG(*ptr);
54 ptr++;
56 return sum;
59 LONG PartitionRDBCheckPartitionTable
61 struct Library *PartitionBase,
62 struct PartitionHandle *root
65 UBYTE i;
66 UBYTE space[root->de.de_SizeBlock<<2];
67 struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)space;
68 struct PartitionType type;
69 struct TagItem tags[] = {{PT_TYPE, (IPTR)&type}, {TAG_DONE, 0}};
71 if (root->root != NULL)
73 GetPartitionAttrs(root, tags);
74 if (
75 root->root->table->type != PHPTT_MBR &&
76 root->root->table->type != PHPTT_EBR ||
77 type.id[0] != 0x30 && type.id[0] != 0x76
80 return 0;
83 for (i=0;i<RDB_LOCATION_LIMIT; i++)
85 if (readBlock(PartitionBase, root, i, rdb) != 0)
86 return 0;
87 if (rdb->rdb_ID == AROS_BE2LONG(IDNAME_RIGIDDISK))
88 break;
90 if (i != RDB_LOCATION_LIMIT)
92 if (calcChkSum((ULONG *)rdb, AROS_BE2LONG(rdb->rdb_SummedLongs))==0)
93 return 1;
95 return 0;
98 void CopyBE2HostDosEnvec(LONG *src, SIPTR *dst, ULONG size) {
99 ULONG count=0;
101 while (count != size)
103 *dst++ = AROS_BE2LONG(*src);
104 src++;
105 count++;
109 void CopyHost2BEDosEnvec(SIPTR *src, ULONG *dst, ULONG size) {
111 ULONG count=0;
113 while (count != size)
115 *dst++ = AROS_LONG2BE(*src);
116 src++;
117 count++;
122 struct BadBlockNode *PartitionRDBNewBadBlock
124 struct Library *PartitionBase,
125 struct PartitionHandle *root,
126 struct BadBlockBlock *buffer
129 struct BadBlockNode *bn;
131 if (
132 (AROS_BE2LONG(buffer->bbb_ID) == IDNAME_BADBLOCK) &&
133 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->bbb_SummedLongs))==0)
136 bn = AllocMem(sizeof(struct BadBlockNode), MEMF_PUBLIC | MEMF_CLEAR);
137 if (bn)
139 CopyMem(buffer, &bn->bbb, sizeof(struct BadBlockBlock));
140 return bn;
143 return NULL;
146 struct PartitionHandle *PartitionRDBNewHandle
148 struct Library *PartitionBase,
149 struct PartitionHandle *root,
150 struct PartitionBlock *buffer
153 struct PartitionBlock *pblock;
154 struct PartitionHandle *ph;
156 if (
157 (AROS_BE2LONG(buffer->pb_ID) == IDNAME_PARTITION) &&
158 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->pb_SummedLongs))==0)
161 ph = AllocMem(sizeof(struct PartitionHandle), MEMF_PUBLIC | MEMF_CLEAR);
162 if (ph)
164 ph->ln.ln_Name = AllocVec(32, MEMF_PUBLIC | MEMF_CLEAR);
165 if (ph->ln.ln_Name)
167 pblock = AllocMem(sizeof(struct PartitionBlock), MEMF_PUBLIC);
168 if (pblock)
170 CopyMem(buffer, pblock, sizeof(struct PartitionBlock));
171 ph->root = root;
172 ph->bd = root->bd;
173 ph->data = pblock;
174 CopyMem(pblock->pb_DriveName+1, ph->ln.ln_Name, pblock->pb_DriveName[0]);
175 ph->ln.ln_Name[pblock->pb_DriveName[0]]=0;
176 CopyBE2HostDosEnvec(pblock->pb_Environment, (SIPTR *)&ph->de, AROS_BE2LONG(((struct DosEnvec *)pblock->pb_Environment)->de_TableSize)+1);
177 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
178 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
179 ph->dg.dg_Heads = ph->de.de_Surfaces;
180 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
181 ph->dg.dg_Cylinders = ph->de.de_HighCyl - ph->de.de_LowCyl + 1;
182 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
183 return ph;
185 FreeVec(ph->ln.ln_Name);
187 FreeMem(ph, sizeof(struct PartitionHandle));
190 return NULL;
193 struct FileSysNode *PartitionRDBNewFileSys
195 struct Library *PartitionBase,
196 struct PartitionHandle *root,
197 struct FileSysHeaderBlock *buffer
200 struct FileSysNode *fn;
202 if (
203 (AROS_BE2LONG(buffer->fhb_ID) == IDNAME_FILESYSHEADER) &&
204 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->fhb_SummedLongs))==0)
207 fn = AllocMem(sizeof(struct FileSysNode), MEMF_PUBLIC | MEMF_CLEAR);
208 if (fn)
210 CopyMem(buffer, &fn->fhb, sizeof(struct FileSysHeaderBlock));
211 return fn;
214 return NULL;
217 ULONG PartitionRDBCalcFSSize
219 struct Library *PartitionBase,
220 struct PartitionHandle *root,
221 struct FileSysNode *fn,
222 struct LoadSegBlock *buffer
225 ULONG size;
226 ULONG block;
228 size = 0;
229 block = AROS_BE2LONG(fn->fhb.fhb_SegListBlocks);
230 while (block != (ULONG)-1)
232 size++;
233 if (readBlock(PartitionBase, root, block, buffer) !=0)
234 return 0;
235 if (
236 (AROS_BE2LONG(buffer->lsb_ID) != IDNAME_LOADSEG) ||
237 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->lsb_SummedLongs)))
239 return 0;
240 block = AROS_BE2LONG(buffer->lsb_Next);
242 return size;
245 void PartitionRDBReadFileSys
247 struct Library *PartitionBase,
248 struct PartitionHandle *root,
249 struct FileSysNode *fn,
250 struct LoadSegBlock *buffer
253 ULONG size;
254 ULONG block;
256 size = PartitionRDBCalcFSSize(PartitionBase, root, fn, buffer);
257 if (size)
259 fn->fsblocks = size;
260 fn->filesystem = AllocVec(size*512, MEMF_PUBLIC);
261 if (fn->filesystem)
263 size = 0;
264 block = AROS_BE2LONG(fn->fhb.fhb_SegListBlocks);
265 while (block != (ULONG)-1)
267 if (readBlock(PartitionBase, root, block, &fn->filesystem[size]) !=0)
268 return;
269 block = AROS_BE2LONG(fn->filesystem[size].lsb_Next);
270 size++;
276 LONG PartitionRDBOpenPartitionTable
278 struct Library *PartitionBase,
279 struct PartitionHandle *root
282 UBYTE buffer[root->de.de_SizeBlock << 2];
283 struct RDBData *data;
284 UBYTE i;
286 data = AllocMem(sizeof(struct RDBData), MEMF_PUBLIC);
287 if (data)
289 for (i=0;i<RDB_LOCATION_LIMIT; i++)
291 if (readBlock(PartitionBase, root, i, buffer) != 0)
292 return 1;
293 CopyMem(buffer, &data->rdb, sizeof(struct RigidDiskBlock));
294 if (data->rdb.rdb_ID == AROS_BE2LONG(IDNAME_RIGIDDISK))
295 break;
297 if (i != RDB_LOCATION_LIMIT)
299 ULONG block;
301 data->rdbblock = i;
302 NEWLIST(&root->table->list);
303 NEWLIST(&data->badblocklist);
304 NEWLIST(&data->fsheaderlist);
305 root->table->data = data;
306 /* take the values of the rdb instead of TD_GEOMETRY */
307 root->dg.dg_SectorSize = AROS_BE2LONG(data->rdb.rdb_BlockBytes);
308 root->dg.dg_Cylinders = AROS_BE2LONG(data->rdb.rdb_Cylinders);
309 root->dg.dg_TrackSectors = AROS_BE2LONG(data->rdb.rdb_Sectors);
310 root->dg.dg_Heads = AROS_BE2LONG(data->rdb.rdb_Heads);
311 /* read bad blocks */
312 block = AROS_BE2LONG(data->rdb.rdb_BadBlockList);
313 while (block != (ULONG)-1)
315 struct BadBlockNode *bn;
317 if (readBlock(PartitionBase, root, block, buffer)==0)
319 bn = PartitionRDBNewBadBlock(PartitionBase, root, (struct BadBlockBlock *)buffer);
320 if (bn != NULL)
322 AddTail(&data->badblocklist, &bn->ln);
323 block = AROS_BE2LONG(bn->bbb.bbb_Next);
325 else
326 break;
328 else
329 break;
331 /* read partition blocks */
332 block = AROS_BE2LONG(data->rdb.rdb_PartitionList);
333 while (block != (ULONG)-1)
335 struct PartitionHandle *ph;
336 if (readBlock(PartitionBase, root, block, buffer)==0)
338 ph = PartitionRDBNewHandle(PartitionBase, root, (struct PartitionBlock *)buffer);
339 if (ph != NULL)
341 AddTail(&root->table->list, &ph->ln);
342 block = AROS_BE2LONG(((struct PartitionBlock *)ph->data)->pb_Next);
344 else
345 break;
347 else
348 break;
350 /* read filesystem blocks */
351 block = AROS_BE2LONG(data->rdb.rdb_FileSysHeaderList);
352 while (block != (ULONG)-1)
354 struct FileSysNode *fn;
356 if (readBlock(PartitionBase, root, block, buffer)==0)
358 fn = PartitionRDBNewFileSys(PartitionBase, root, (struct FileSysHeaderBlock *)buffer);
359 if (fn != NULL)
361 AddTail(&data->fsheaderlist, &fn->ln);
362 PartitionRDBReadFileSys(PartitionBase, root, fn, (struct LoadSegBlock *)buffer);
363 block = AROS_BE2LONG(fn->fhb.fhb_Next);
365 else
366 break;
368 else
369 break;
371 return 0;
373 FreeMem(data, sizeof(struct RDBData));
375 return 1;
378 void PartitionRDBFreeHandle
380 struct Library *PartitionBase,
381 struct PartitionHandle *ph
384 ClosePartitionTable(ph);
385 Remove(&ph->ln);
386 FreeMem(ph->data, sizeof(struct PartitionBlock));
387 FreeVec(ph->ln.ln_Name);
388 FreeMem(ph, sizeof(struct PartitionHandle));
391 void PartitionRDBClosePartitionTable
393 struct Library *PartitionBase,
394 struct PartitionHandle *root
397 struct PartitionHandle *ph;
398 struct BadBlockNode *bn;
399 struct FileSysNode *fn;
400 struct RDBData *data;
402 while ((ph = (struct PartitionHandle *)RemTail(&root->table->list)))
403 PartitionRDBFreeHandle(PartitionBase, ph);
404 data = (struct RDBData *)root->table->data;
405 while ((bn = (struct BadBlockNode *)RemTail(&data->badblocklist)))
406 FreeMem(bn, sizeof(struct BadBlockNode));
407 while ((fn = (struct FileSysNode *)RemTail(&data->fsheaderlist)))
409 if (fn->filesystem)
410 FreeVec(fn->filesystem);
411 FreeMem(fn, sizeof(struct FileSysNode));
413 FreeMem(data, sizeof(struct RDBData));
416 ULONG PartitionRDBWriteFileSys
418 struct Library *PartitionBase,
419 struct PartitionHandle *root,
420 struct FileSysNode *fn,
421 ULONG block
424 ULONG size;
426 if (fn->filesystem)
428 size = 0;
429 while (size != fn->fsblocks)
431 fn->filesystem[size].lsb_Next = (size+1) != fn->fsblocks ? AROS_LONG2BE(block+1) : (ULONG)-1;
432 fn->filesystem[size].lsb_ChkSum = 0;
433 fn->filesystem[size].lsb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&fn->filesystem[size], AROS_LONG2BE(fn->filesystem[size].lsb_SummedLongs)));
434 #if RDB_WRITE
435 if (writeBlock(PartitionBase, root, block++, &fn->filesystem[size]) != 0)
436 return block;
437 #else
438 kprintf("RDB-write: block=%ld, type=LSEG\n", block);
439 block++;
440 #endif
441 size++;
444 return block;
447 LONG PartitionRDBWritePartitionTable
449 struct Library *PartitionBase,
450 struct PartitionHandle *root
453 UBYTE buffer[root->de.de_SizeBlock << 2];
454 struct RDBData *data;
455 struct PartitionHandle *ph;
456 struct PartitionBlock *pblock;
457 struct BadBlockNode *bn;
458 struct FileSysNode *fn;
459 ULONG block;
461 data = root->table->data;
462 block = data->rdbblock+1; /* RDB will be written at the end */
463 fillMem((UBYTE *)buffer, root->de.de_SizeBlock << 2, 0);
465 /* write bad blocks */
466 bn = (struct BadBlockNode *)data->badblocklist.lh_Head;
467 if (bn->ln.ln_Succ)
468 data->rdb.rdb_BadBlockList = block;
469 else
470 data->rdb.rdb_BadBlockList = (ULONG)-1;
471 while (bn->ln.ln_Succ)
473 bn->bbb.bbb_Next = bn->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block+1) : (ULONG)-1;
474 bn->bbb.bbb_ChkSum = 0;
475 bn->bbb.bbb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&bn->bbb, AROS_BE2LONG(bn->bbb.bbb_SummedLongs)));
476 CopyMem(&bn->bbb, buffer, sizeof(struct BadBlockBlock));
477 #if RDB_WRITE
478 writeBlock(PartitionBase, root, block++, buffer);
479 #else
480 kprintf("RDB-write: block=%ld, type=BADB\n", block);
481 block++;
482 #endif
484 bn = (struct BadBlockNode *)bn->ln.ln_Succ;
487 /* write partition blocks */
488 ph = (struct PartitionHandle *)root->table->list.lh_Head;
489 if (ph->ln.ln_Succ)
490 data->rdb.rdb_PartitionList = AROS_LONG2BE(block);
491 else
492 data->rdb.rdb_PartitionList = (ULONG)-1;
493 while (ph->ln.ln_Succ)
495 pblock = (struct PartitionBlock *)ph->data;
496 pblock->pb_Next = ph->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block+1) : (ULONG)-1;
497 pblock->pb_ChkSum = 0;
498 pblock->pb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)pblock, AROS_BE2LONG(pblock->pb_SummedLongs)));
499 CopyMem(pblock, buffer, sizeof(struct PartitionBlock));
500 #if RDB_WRITE
501 writeBlock(PartitionBase, root, block++, buffer);
502 #else
503 kprintf("RDB-write: block=%ld, type=PART\n", block);
504 block++;
505 #endif
506 ph = (struct PartitionHandle *)ph->ln.ln_Succ;
509 /* write filesystem blocks */
510 fn = (struct FileSysNode *)data->fsheaderlist.lh_Head;
511 if (fn->ln.ln_Succ)
512 data->rdb.rdb_FileSysHeaderList = AROS_LONG2BE(block);
513 else
514 data->rdb.rdb_FileSysHeaderList = (ULONG)-1;
515 while (fn->ln.ln_Succ)
517 ULONG fshblock;
519 fshblock = block;
520 block++; /* header block will be written later */
521 fn->fhb.fhb_SegListBlocks = AROS_LONG2BE(block);
522 /* write filesystem LSEG blocks */
523 block = PartitionRDBWriteFileSys(PartitionBase, root, fn, block);
524 fn->fhb.fhb_Next = fn->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block) : (ULONG)-1;
525 fn->fhb.fhb_ChkSum = 0;
526 CopyMem(&fn->fhb, buffer, sizeof(struct FileSysHeaderBlock));
527 ((struct FileSysHeaderBlock *)buffer)->fhb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)buffer, AROS_BE2LONG(fn->fhb.fhb_SummedLongs)));
528 #if RDB_WRITE
529 writeBlock(PartitionBase, root, fshblock, buffer);
530 #else
531 kprintf("RDB-write: block=%ld, type=FSHD\n", fshblock);
532 #endif
533 fn = (struct FileSysNode *)fn->ln.ln_Succ;
535 data->rdb.rdb_HighRDSKBlock = AROS_LONG2BE(block-1);
536 data->rdb.rdb_ChkSum = 0;
537 data->rdb.rdb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&data->rdb, AROS_BE2LONG(data->rdb.rdb_SummedLongs)));
538 CopyMem(&data->rdb, buffer, sizeof(struct RigidDiskBlock));
539 #if RDB_WRITE
540 writeBlock(PartitionBase, root, data->rdbblock, buffer);
541 #else
542 kprintf("RDB-write: block=%ld, type=RDSK\n", data->rdbblock);
543 #endif
544 return 0;
547 LONG PartitionRDBCreatePartitionTable
549 struct Library *PartitionBase,
550 struct PartitionHandle *ph
553 struct RDBData *data;
554 ULONG i;
556 data = AllocMem(sizeof(struct RDBData), MEMF_PUBLIC | MEMF_CLEAR);
557 if (data)
559 ph->table->data = data;
560 data->rdb.rdb_ID = AROS_LONG2BE(IDNAME_RIGIDDISK);
561 data->rdb.rdb_SummedLongs = AROS_LONG2BE(sizeof(struct RigidDiskBlock)/4);
562 data->rdb.rdb_BlockBytes = AROS_LONG2BE(ph->dg.dg_SectorSize);
563 data->rdb.rdb_BadBlockList = (ULONG)-1;
564 data->rdb.rdb_PartitionList = (ULONG)-1;
565 data->rdb.rdb_FileSysHeaderList = (ULONG)-1;
566 data->rdb.rdb_DriveInit = (ULONG)-1;
567 for (i=0;i<6;i++)
568 data->rdb.rdb_Reserved1[i] = (ULONG)-1;
569 data->rdb.rdb_Cylinders = AROS_LONG2BE(ph->dg.dg_Cylinders);
570 data->rdb.rdb_Sectors = AROS_LONG2BE(ph->dg.dg_TrackSectors);
571 data->rdb.rdb_Heads = AROS_LONG2BE(ph->dg.dg_Heads);
573 data->rdb.rdb_Park = data->rdb.rdb_Cylinders;
574 data->rdb.rdb_WritePreComp = data->rdb.rdb_Cylinders;
575 data->rdb.rdb_ReducedWrite = data->rdb.rdb_Cylinders;
576 /* StepRate */
578 data->rdb.rdb_RDBBlocksLo = AROS_LONG2BE(1); /* leave a block for PC */
579 data->rdb.rdb_RDBBlocksHi = AROS_LONG2BE((ph->dg.dg_Heads*ph->dg.dg_TrackSectors*2)-1); /* two cylinders */
580 data->rdb.rdb_LoCylinder = AROS_LONG2BE(2);
581 data->rdb.rdb_HiCylinder = AROS_LONG2BE(ph->dg.dg_Cylinders-1);
582 data->rdb.rdb_CylBlocks = AROS_LONG2BE(ph->dg.dg_Heads*ph->dg.dg_TrackSectors);
583 /* AutoParkSeconds */
584 /* DiskVendor */
585 /* DiskProduct */
586 /* DiskRevision */
587 /* ControllerVendor */
588 /* ControllerProduct */
589 /* ControllerRevision */
591 data->rdbblock = 1;
592 NEWLIST(&data->badblocklist);
593 NEWLIST(&data->fsheaderlist);
594 NEWLIST(&ph->table->list);
595 return 0;
597 return 1;
600 LONG PartitionRDBGetPartitionTableAttrs
602 struct Library *PartitionBase,
603 struct PartitionHandle *root,
604 struct TagItem *taglist
608 while (taglist[0].ti_Tag != TAG_DONE)
611 switch (taglist[0].ti_Tag)
613 case PTT_TYPE:
614 *((LONG *)taglist[0].ti_Data) = root->table->type;
615 break;
616 case PTT_RESERVED:
617 *((LONG *)taglist[0].ti_Data) =
618 root->de.de_Surfaces*root->de.de_BlocksPerTrack*2; /* 2 cylinders */
619 break;
621 taglist++;
623 return 0;
626 LONG PartitionRDBSetPartitionTableAttrs
628 struct Library *PartitionBase,
629 struct PartitionHandle *root,
630 struct TagItem *taglist
634 while (taglist[0].ti_Tag != TAG_DONE)
637 switch (taglist[0].ti_Tag)
640 taglist++;
642 return 0;
645 LONG PartitionRDBGetPartitionAttrs
647 struct Library *PartitionBase,
648 struct PartitionHandle *ph,
649 struct TagItem *taglist
653 while (taglist[0].ti_Tag != TAG_DONE)
655 struct PartitionBlock *data = (struct PartitionBlock *)ph->data;
657 switch (taglist[0].ti_Tag)
659 case PT_GEOMETRY:
661 struct DriveGeometry *dg = (struct DriveGeometry *)taglist[0].ti_Data;
662 CopyMem(&ph->dg, dg, sizeof(struct DriveGeometry));
664 break;
665 case PT_DOSENVEC:
666 CopyMem(&ph->de, (struct DosEnvec *)taglist[0].ti_Data, sizeof(struct DosEnvec));
667 break;
668 case PT_TYPE:
670 struct PartitionType *ptype=(struct PartitionType *)taglist[0].ti_Data;
671 ULONG dt = AROS_LONG2BE(ph->de.de_DosType);
673 CopyMem(&dt, ptype->id, 4);
674 ptype->id_len = 4;
676 break;
677 case PT_NAME:
678 CopyMem(ph->ln.ln_Name, (UBYTE *)taglist[0].ti_Data, 32);
679 break;
680 case PT_BOOTABLE:
681 *((LONG *)taglist[0].ti_Data) = (AROS_BE2LONG(data->pb_Flags) & PBFF_BOOTABLE) ? TRUE : FALSE;
682 break;
683 case PT_AUTOMOUNT:
684 *((LONG *)taglist[0].ti_Data) = (AROS_BE2LONG(data->pb_Flags) & PBFF_NOMOUNT) ? FALSE : TRUE;
685 break;
687 taglist++;
689 return 0;
692 LONG PartitionRDBSetPartitionAttrs
694 struct Library *PartitionBase,
695 struct PartitionHandle *ph,
696 struct TagItem *taglist
700 while (taglist[0].ti_Tag != TAG_DONE)
702 struct PartitionBlock *data = (struct PartitionBlock *)ph->data;
704 switch (taglist[0].ti_Tag)
706 case PT_DOSENVEC:
708 struct DosEnvec *de = (struct DosEnvec *)taglist[0].ti_Data;
710 CopyMem(de, &ph->de, (de->de_TableSize+1)*sizeof(IPTR));
711 CopyHost2BEDosEnvec((SIPTR *)de, data->pb_Environment, de->de_TableSize+1);
713 break;
714 case PT_TYPE:
716 struct PartitionType *ptype=(struct PartitionType *)taglist[0].ti_Data;
717 ULONG dt;
719 CopyMem(ptype->id, &dt, 4);
720 ph->de.de_DosType = AROS_BE2LONG(dt);
721 data->pb_Environment[DE_DOSTYPE] = dt;
723 break;
724 case PT_NAME:
726 STRPTR name = (STRPTR)taglist[0].ti_Data;
727 ULONG len = strlen(name);
729 CopyMem(name, ph->ln.ln_Name, len+1);
730 CopyMem(name, data->pb_DriveName+1, len);
731 data->pb_DriveName[len+1] = 0;
732 data->pb_DriveName[0] = len;
734 break;
735 case PT_BOOTABLE:
736 if (taglist[0].ti_Data)
737 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) | PBFF_BOOTABLE);
738 else
739 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) & ~PBFF_BOOTABLE);
740 break;
741 case PT_AUTOMOUNT:
742 if (taglist[0].ti_Data)
743 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) & ~PBFF_NOMOUNT);
744 else
745 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) | PBFF_NOMOUNT);
746 break;
748 taglist++;
750 return 0;
753 struct PartitionHandle *PartitionRDBAddPartition
755 struct Library *PartitionBase,
756 struct PartitionHandle *root,
757 struct TagItem *taglist
761 if (findTagItem(PT_DOSENVEC, taglist) != NULL)
763 struct PartitionBlock *pblock;
764 struct PartitionHandle *ph;
765 struct PartitionHandle *oph;
767 ph = AllocMem(sizeof(struct PartitionHandle), MEMF_PUBLIC | MEMF_CLEAR);
768 if (ph)
770 ph->ln.ln_Name = AllocVec(32, MEMF_PUBLIC | MEMF_CLEAR);
771 if (ph->ln.ln_Name)
773 pblock = AllocMem(sizeof(struct PartitionBlock), MEMF_PUBLIC | MEMF_CLEAR);
774 if (pblock)
776 ph->root = root;
777 ph->bd = root->bd;
778 ph->data = pblock;
779 pblock->pb_ID = AROS_LONG2BE(IDNAME_PARTITION);
780 pblock->pb_SummedLongs = AROS_LONG2BE(sizeof(struct PartitionBlock)/4);
781 PartitionRDBSetPartitionAttrs(PartitionBase, ph, taglist);
782 oph = (struct PartitionHandle *)root->table->list.lh_Head;
783 while (oph->ln.ln_Succ)
785 if (ph->de.de_LowCyl<oph->de.de_LowCyl)
786 break;
787 oph = (struct PartitionHandle *)oph->ln.ln_Succ;
789 if (oph->ln.ln_Succ)
791 oph = (struct PartitionHandle *)oph->ln.ln_Pred;
792 if (oph->ln.ln_Pred)
794 Insert(&root->table->list, &ph->ln, &oph->ln);
796 else
797 AddHead(&root->table->list, &ph->ln);
799 else
800 AddTail(&root->table->list, &ph->ln);
801 if (findTagItem(PT_DOSENVEC, taglist) == NULL)
803 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
804 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
805 ph->dg.dg_Heads = ph->de.de_Surfaces;
806 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
807 ph->dg.dg_Cylinders = ph->de.de_HighCyl - ph->de.de_LowCyl + 1;
808 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
810 return ph;
812 FreeVec(ph->ln.ln_Name);
814 FreeMem(ph, sizeof(struct PartitionHandle));
817 return NULL;
820 void PartitionRDBDeletePartition
822 struct Library *PartitionBase,
823 struct PartitionHandle *ph
827 PartitionRDBFreeHandle(PartitionBase, ph);
830 struct PartitionAttribute PartitionRDBPartitionTableAttrs[]=
832 {PTTA_TYPE, PLAM_READ},
833 {PTTA_RESERVED, PLAM_READ},
834 {PTTA_DONE, 0}
837 struct PartitionAttribute *PartitionRDBQueryPartitionTableAttrs(struct Library *PartitionBase)
839 return PartitionRDBPartitionTableAttrs;
842 struct PartitionAttribute PartitionRDBPartitionAttrs[]=
844 #warning "TODO: implement write"
845 {PTA_GEOMETRY, PLAM_READ},
846 {PTA_DOSENVEC, PLAM_READ | PLAM_WRITE},
847 {PTA_TYPE, PLAM_READ | PLAM_WRITE},
848 {PTA_NAME, PLAM_READ | PLAM_WRITE},
849 {PTA_BOOTABLE, PLAM_READ | PLAM_WRITE},
850 {PTA_AUTOMOUNT, PLAM_READ | PLAM_WRITE},
851 {PTA_DONE, 0}
854 struct PartitionAttribute *PartitionRDBQueryPartitionAttrs(struct Library *PartitionBase)
856 return PartitionRDBPartitionAttrs;
859 ULONG PartitionRDBDestroyPartitionTable
861 struct Library *PartitionBase,
862 struct PartitionHandle *root
865 struct RDBData *data;
866 UBYTE buffer[root->de.de_SizeBlock << 2];
868 data = root->table->data;
869 CopyMem(&data->rdb, buffer, sizeof(struct RigidDiskBlock));
870 ((struct RigidDiskBlock *)buffer)->rdb_ID = 0;
871 if (writeBlock(PartitionBase, root, data->rdbblock, buffer))
872 return 1;
873 return 0;
876 struct PTFunctionTable PartitionRDB =
878 PHPTT_RDB,
879 "RDB",
880 PartitionRDBCheckPartitionTable,
881 PartitionRDBOpenPartitionTable,
882 PartitionRDBClosePartitionTable,
883 PartitionRDBWritePartitionTable,
884 PartitionRDBCreatePartitionTable,
885 PartitionRDBAddPartition,
886 PartitionRDBDeletePartition,
887 PartitionRDBGetPartitionTableAttrs,
888 PartitionRDBSetPartitionTableAttrs,
889 PartitionRDBGetPartitionAttrs,
890 PartitionRDBSetPartitionAttrs,
891 PartitionRDBQueryPartitionTableAttrs,
892 PartitionRDBQueryPartitionAttrs,
893 PartitionRDBDestroyPartitionTable