Fixed broken copyright symbol.
[cake.git] / workbench / libs / partition / partitionrdb.c
blob6a408fbce44fc8df6f89403404f83aa1195dae8a
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;
69 for (i=0;i<RDB_LOCATION_LIMIT; i++)
71 if (readBlock(PartitionBase, root, i, rdb) != 0)
72 return 0;
73 if (rdb->rdb_ID == AROS_BE2LONG(IDNAME_RIGIDDISK))
74 break;
76 if (i != RDB_LOCATION_LIMIT)
78 if (calcChkSum((ULONG *)rdb, AROS_BE2LONG(rdb->rdb_SummedLongs))==0)
79 return 1;
81 return 0;
84 void CopyBE2HostDosEnvec(LONG *src, SIPTR *dst, ULONG size) {
85 ULONG count=0;
87 while (count != size)
89 *dst++ = AROS_BE2LONG(*src);
90 src++;
91 count++;
95 void CopyHost2BEDosEnvec(SIPTR *src, ULONG *dst, ULONG size) {
97 ULONG count=0;
99 while (count != size)
101 *dst++ = AROS_LONG2BE(*src);
102 src++;
103 count++;
108 struct BadBlockNode *PartitionRDBNewBadBlock
110 struct Library *PartitionBase,
111 struct PartitionHandle *root,
112 struct BadBlockBlock *buffer
115 struct BadBlockNode *bn;
117 if (
118 (AROS_BE2LONG(buffer->bbb_ID) == IDNAME_BADBLOCK) &&
119 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->bbb_SummedLongs))==0)
122 bn = AllocMem(sizeof(struct BadBlockNode), MEMF_PUBLIC | MEMF_CLEAR);
123 if (bn)
125 CopyMem(buffer, &bn->bbb, sizeof(struct BadBlockBlock));
126 return bn;
129 return NULL;
132 struct PartitionHandle *PartitionRDBNewHandle
134 struct Library *PartitionBase,
135 struct PartitionHandle *root,
136 struct PartitionBlock *buffer
139 struct PartitionBlock *pblock;
140 struct PartitionHandle *ph;
142 if (
143 (AROS_BE2LONG(buffer->pb_ID) == IDNAME_PARTITION) &&
144 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->pb_SummedLongs))==0)
147 ph = AllocMem(sizeof(struct PartitionHandle), MEMF_PUBLIC | MEMF_CLEAR);
148 if (ph)
150 ph->ln.ln_Name = AllocVec(32, MEMF_PUBLIC | MEMF_CLEAR);
151 if (ph->ln.ln_Name)
153 pblock = AllocMem(sizeof(struct PartitionBlock), MEMF_PUBLIC);
154 if (pblock)
156 CopyMem(buffer, pblock, sizeof(struct PartitionBlock));
157 ph->root = root;
158 ph->bd = root->bd;
159 ph->data = pblock;
160 CopyMem(pblock->pb_DriveName+1, ph->ln.ln_Name, pblock->pb_DriveName[0]);
161 ph->ln.ln_Name[pblock->pb_DriveName[0]]=0;
162 CopyBE2HostDosEnvec(pblock->pb_Environment, (SIPTR *)&ph->de, AROS_BE2LONG(((struct DosEnvec *)pblock->pb_Environment)->de_TableSize)+1);
163 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
164 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
165 ph->dg.dg_Heads = ph->de.de_Surfaces;
166 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
167 ph->dg.dg_Cylinders = ph->de.de_HighCyl - ph->de.de_LowCyl + 1;
168 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
169 return ph;
171 FreeVec(ph->ln.ln_Name);
173 FreeMem(ph, sizeof(struct PartitionHandle));
176 return NULL;
179 struct FileSysNode *PartitionRDBNewFileSys
181 struct Library *PartitionBase,
182 struct PartitionHandle *root,
183 struct FileSysHeaderBlock *buffer
186 struct FileSysNode *fn;
188 if (
189 (AROS_BE2LONG(buffer->fhb_ID) == IDNAME_FILESYSHEADER) &&
190 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->fhb_SummedLongs))==0)
193 fn = AllocMem(sizeof(struct FileSysNode), MEMF_PUBLIC | MEMF_CLEAR);
194 if (fn)
196 CopyMem(buffer, &fn->fhb, sizeof(struct FileSysHeaderBlock));
197 return fn;
200 return NULL;
203 ULONG PartitionRDBCalcFSSize
205 struct Library *PartitionBase,
206 struct PartitionHandle *root,
207 struct FileSysNode *fn,
208 struct LoadSegBlock *buffer
211 ULONG size;
212 ULONG block;
214 size = 0;
215 block = AROS_BE2LONG(fn->fhb.fhb_SegListBlocks);
216 while (block != (ULONG)-1)
218 size++;
219 if (readBlock(PartitionBase, root, block, buffer) !=0)
220 return 0;
221 if (
222 (AROS_BE2LONG(buffer->lsb_ID) != IDNAME_LOADSEG) ||
223 (calcChkSum((ULONG *)buffer, AROS_BE2LONG(buffer->lsb_SummedLongs)))
225 return 0;
226 block = AROS_BE2LONG(buffer->lsb_Next);
228 return size;
231 void PartitionRDBReadFileSys
233 struct Library *PartitionBase,
234 struct PartitionHandle *root,
235 struct FileSysNode *fn,
236 struct LoadSegBlock *buffer
239 ULONG size;
240 ULONG block;
242 size = PartitionRDBCalcFSSize(PartitionBase, root, fn, buffer);
243 if (size)
245 fn->fsblocks = size;
246 fn->filesystem = AllocVec(size*512, MEMF_PUBLIC);
247 if (fn->filesystem)
249 size = 0;
250 block = AROS_BE2LONG(fn->fhb.fhb_SegListBlocks);
251 while (block != (ULONG)-1)
253 if (readBlock(PartitionBase, root, block, &fn->filesystem[size]) !=0)
254 return;
255 block = AROS_BE2LONG(fn->filesystem[size].lsb_Next);
256 size++;
262 LONG PartitionRDBOpenPartitionTable
264 struct Library *PartitionBase,
265 struct PartitionHandle *root
268 UBYTE buffer[root->de.de_SizeBlock << 2];
269 struct RDBData *data;
270 UBYTE i;
272 data = AllocMem(sizeof(struct RDBData), MEMF_PUBLIC);
273 if (data)
275 for (i=0;i<RDB_LOCATION_LIMIT; i++)
277 if (readBlock(PartitionBase, root, i, buffer) != 0)
278 return 1;
279 CopyMem(buffer, &data->rdb, sizeof(struct RigidDiskBlock));
280 if (data->rdb.rdb_ID == AROS_BE2LONG(IDNAME_RIGIDDISK))
281 break;
283 if (i != RDB_LOCATION_LIMIT)
285 ULONG block;
287 data->rdbblock = i;
288 NEWLIST(&root->table->list);
289 NEWLIST(&data->badblocklist);
290 NEWLIST(&data->fsheaderlist);
291 root->table->data = data;
292 /* take the values of the rdb instead of TD_GEOMETRY */
293 root->dg.dg_SectorSize = AROS_BE2LONG(data->rdb.rdb_BlockBytes);
294 root->dg.dg_Cylinders = AROS_BE2LONG(data->rdb.rdb_Cylinders);
295 root->dg.dg_TrackSectors = AROS_BE2LONG(data->rdb.rdb_Sectors);
296 root->dg.dg_Heads = AROS_BE2LONG(data->rdb.rdb_Heads);
297 /* read bad blocks */
298 block = AROS_BE2LONG(data->rdb.rdb_BadBlockList);
299 while (block != (ULONG)-1)
301 struct BadBlockNode *bn;
303 if (readBlock(PartitionBase, root, block, buffer)==0)
305 bn = PartitionRDBNewBadBlock(PartitionBase, root, (struct BadBlockBlock *)buffer);
306 if (bn != NULL)
308 AddTail(&data->badblocklist, &bn->ln);
309 block = AROS_BE2LONG(bn->bbb.bbb_Next);
311 else
312 break;
314 else
315 break;
317 /* read partition blocks */
318 block = AROS_BE2LONG(data->rdb.rdb_PartitionList);
319 while (block != (ULONG)-1)
321 struct PartitionHandle *ph;
322 if (readBlock(PartitionBase, root, block, buffer)==0)
324 ph = PartitionRDBNewHandle(PartitionBase, root, (struct PartitionBlock *)buffer);
325 if (ph != NULL)
327 AddTail(&root->table->list, &ph->ln);
328 block = AROS_BE2LONG(((struct PartitionBlock *)ph->data)->pb_Next);
330 else
331 break;
333 else
334 break;
336 /* read filesystem blocks */
337 block = AROS_BE2LONG(data->rdb.rdb_FileSysHeaderList);
338 while (block != (ULONG)-1)
340 struct FileSysNode *fn;
342 if (readBlock(PartitionBase, root, block, buffer)==0)
344 fn = PartitionRDBNewFileSys(PartitionBase, root, (struct FileSysHeaderBlock *)buffer);
345 if (fn != NULL)
347 AddTail(&data->fsheaderlist, &fn->ln);
348 PartitionRDBReadFileSys(PartitionBase, root, fn, (struct LoadSegBlock *)buffer);
349 block = AROS_BE2LONG(fn->fhb.fhb_Next);
351 else
352 break;
354 else
355 break;
357 return 0;
359 FreeMem(data, sizeof(struct RDBData));
361 return 1;
364 void PartitionRDBFreeHandle
366 struct Library *PartitionBase,
367 struct PartitionHandle *ph
370 ClosePartitionTable(ph);
371 Remove(&ph->ln);
372 FreeMem(ph->data, sizeof(struct PartitionBlock));
373 FreeVec(ph->ln.ln_Name);
374 FreeMem(ph, sizeof(struct PartitionHandle));
377 void PartitionRDBClosePartitionTable
379 struct Library *PartitionBase,
380 struct PartitionHandle *root
383 struct PartitionHandle *ph;
384 struct BadBlockNode *bn;
385 struct FileSysNode *fn;
386 struct RDBData *data;
388 while ((ph = (struct PartitionHandle *)RemTail(&root->table->list)))
389 PartitionRDBFreeHandle(PartitionBase, ph);
390 data = (struct RDBData *)root->table->data;
391 while ((bn = (struct BadBlockNode *)RemTail(&data->badblocklist)))
392 FreeMem(bn, sizeof(struct BadBlockNode));
393 while ((fn = (struct FileSysNode *)RemTail(&data->fsheaderlist)))
395 if (fn->filesystem)
396 FreeVec(fn->filesystem);
397 FreeMem(fn, sizeof(struct FileSysNode));
399 FreeMem(data, sizeof(struct RDBData));
402 ULONG PartitionRDBWriteFileSys
404 struct Library *PartitionBase,
405 struct PartitionHandle *root,
406 struct FileSysNode *fn,
407 ULONG block
410 ULONG size;
412 if (fn->filesystem)
414 size = 0;
415 while (size != fn->fsblocks)
417 fn->filesystem[size].lsb_Next = (size+1) != fn->fsblocks ? AROS_LONG2BE(block+1) : (ULONG)-1;
418 fn->filesystem[size].lsb_ChkSum = 0;
419 fn->filesystem[size].lsb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&fn->filesystem[size], AROS_LONG2BE(fn->filesystem[size].lsb_SummedLongs)));
420 #if RDB_WRITE
421 if (writeBlock(PartitionBase, root, block++, &fn->filesystem[size]) != 0)
422 return block;
423 #else
424 kprintf("RDB-write: block=%ld, type=LSEG\n", block);
425 block++;
426 #endif
427 size++;
430 return block;
433 LONG PartitionRDBWritePartitionTable
435 struct Library *PartitionBase,
436 struct PartitionHandle *root
439 UBYTE buffer[root->de.de_SizeBlock << 2];
440 struct RDBData *data;
441 struct PartitionHandle *ph;
442 struct PartitionBlock *pblock;
443 struct BadBlockNode *bn;
444 struct FileSysNode *fn;
445 ULONG block;
447 data = root->table->data;
448 block = data->rdbblock+1; /* RDB will be written at the end */
449 fillMem((UBYTE *)buffer, root->de.de_SizeBlock << 2, 0);
451 /* write bad blocks */
452 bn = (struct BadBlockNode *)data->badblocklist.lh_Head;
453 if (bn->ln.ln_Succ)
454 data->rdb.rdb_BadBlockList = block;
455 else
456 data->rdb.rdb_BadBlockList = (ULONG)-1;
457 while (bn->ln.ln_Succ)
459 bn->bbb.bbb_Next = bn->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block+1) : (ULONG)-1;
460 bn->bbb.bbb_ChkSum = 0;
461 bn->bbb.bbb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&bn->bbb, AROS_BE2LONG(bn->bbb.bbb_SummedLongs)));
462 CopyMem(&bn->bbb, buffer, sizeof(struct BadBlockBlock));
463 #if RDB_WRITE
464 writeBlock(PartitionBase, root, block++, buffer);
465 #else
466 kprintf("RDB-write: block=%ld, type=BADB\n", block);
467 block++;
468 #endif
470 bn = (struct BadBlockNode *)bn->ln.ln_Succ;
473 /* write partition blocks */
474 ph = (struct PartitionHandle *)root->table->list.lh_Head;
475 if (ph->ln.ln_Succ)
476 data->rdb.rdb_PartitionList = AROS_LONG2BE(block);
477 else
478 data->rdb.rdb_PartitionList = (ULONG)-1;
479 while (ph->ln.ln_Succ)
481 pblock = (struct PartitionBlock *)ph->data;
482 pblock->pb_Next = ph->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block+1) : (ULONG)-1;
483 pblock->pb_ChkSum = 0;
484 pblock->pb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)pblock, AROS_BE2LONG(pblock->pb_SummedLongs)));
485 CopyMem(pblock, buffer, sizeof(struct PartitionBlock));
486 #if RDB_WRITE
487 writeBlock(PartitionBase, root, block++, buffer);
488 #else
489 kprintf("RDB-write: block=%ld, type=PART\n", block);
490 block++;
491 #endif
492 ph = (struct PartitionHandle *)ph->ln.ln_Succ;
495 /* write filesystem blocks */
496 fn = (struct FileSysNode *)data->fsheaderlist.lh_Head;
497 if (fn->ln.ln_Succ)
498 data->rdb.rdb_FileSysHeaderList = AROS_LONG2BE(block);
499 else
500 data->rdb.rdb_FileSysHeaderList = (ULONG)-1;
501 while (fn->ln.ln_Succ)
503 ULONG fshblock;
505 fshblock = block;
506 block++; /* header block will be written later */
507 fn->fhb.fhb_SegListBlocks = AROS_LONG2BE(block);
508 /* write filesystem LSEG blocks */
509 block = PartitionRDBWriteFileSys(PartitionBase, root, fn, block);
510 fn->fhb.fhb_Next = fn->ln.ln_Succ->ln_Succ ? AROS_LONG2BE(block) : (ULONG)-1;
511 fn->fhb.fhb_ChkSum = 0;
512 CopyMem(&fn->fhb, buffer, sizeof(struct FileSysHeaderBlock));
513 ((struct FileSysHeaderBlock *)buffer)->fhb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)buffer, AROS_BE2LONG(fn->fhb.fhb_SummedLongs)));
514 #if RDB_WRITE
515 writeBlock(PartitionBase, root, fshblock, buffer);
516 #else
517 kprintf("RDB-write: block=%ld, type=FSHD\n", fshblock);
518 #endif
519 fn = (struct FileSysNode *)fn->ln.ln_Succ;
521 data->rdb.rdb_HighRDSKBlock = AROS_LONG2BE(block-1);
522 data->rdb.rdb_ChkSum = 0;
523 data->rdb.rdb_ChkSum = AROS_LONG2BE(0-calcChkSum((ULONG *)&data->rdb, AROS_BE2LONG(data->rdb.rdb_SummedLongs)));
524 CopyMem(&data->rdb, buffer, sizeof(struct RigidDiskBlock));
525 #if RDB_WRITE
526 writeBlock(PartitionBase, root, data->rdbblock, buffer);
527 #else
528 kprintf("RDB-write: block=%ld, type=RDSK\n", data->rdbblock);
529 #endif
530 return 0;
533 LONG PartitionRDBCreatePartitionTable
535 struct Library *PartitionBase,
536 struct PartitionHandle *ph
539 struct RDBData *data;
540 ULONG i;
542 data = AllocMem(sizeof(struct RDBData), MEMF_PUBLIC | MEMF_CLEAR);
543 if (data)
545 ph->table->data = data;
546 data->rdb.rdb_ID = AROS_LONG2BE(IDNAME_RIGIDDISK);
547 data->rdb.rdb_SummedLongs = AROS_LONG2BE(sizeof(struct RigidDiskBlock)/4);
548 data->rdb.rdb_BlockBytes = AROS_LONG2BE(ph->dg.dg_SectorSize);
549 data->rdb.rdb_BadBlockList = (ULONG)-1;
550 data->rdb.rdb_PartitionList = (ULONG)-1;
551 data->rdb.rdb_FileSysHeaderList = (ULONG)-1;
552 data->rdb.rdb_DriveInit = (ULONG)-1;
553 for (i=0;i<6;i++)
554 data->rdb.rdb_Reserved1[i] = (ULONG)-1;
555 data->rdb.rdb_Cylinders = AROS_LONG2BE(ph->dg.dg_Cylinders);
556 data->rdb.rdb_Sectors = AROS_LONG2BE(ph->dg.dg_TrackSectors);
557 data->rdb.rdb_Heads = AROS_LONG2BE(ph->dg.dg_Heads);
559 data->rdb.rdb_Park = data->rdb.rdb_Cylinders;
560 data->rdb.rdb_WritePreComp = data->rdb.rdb_Cylinders;
561 data->rdb.rdb_ReducedWrite = data->rdb.rdb_Cylinders;
562 /* StepRate */
564 data->rdb.rdb_RDBBlocksLo = AROS_LONG2BE(1); /* leave a block for PC */
565 data->rdb.rdb_RDBBlocksHi = AROS_LONG2BE((ph->dg.dg_Heads*ph->dg.dg_TrackSectors*2)-1); /* two cylinders */
566 data->rdb.rdb_LoCylinder = AROS_LONG2BE(2);
567 data->rdb.rdb_HiCylinder = AROS_LONG2BE(ph->dg.dg_Cylinders-1);
568 data->rdb.rdb_CylBlocks = AROS_LONG2BE(ph->dg.dg_Heads*ph->dg.dg_TrackSectors);
569 /* AutoParkSeconds */
570 /* DiskVendor */
571 /* DiskProduct */
572 /* DiskRevision */
573 /* ControllerVendor */
574 /* ControllerProduct */
575 /* ControllerRevision */
577 data->rdbblock = 1;
578 NEWLIST(&data->badblocklist);
579 NEWLIST(&data->fsheaderlist);
580 NEWLIST(&ph->table->list);
581 return 0;
583 return 1;
586 LONG PartitionRDBGetPartitionTableAttrs
588 struct Library *PartitionBase,
589 struct PartitionHandle *root,
590 struct TagItem *taglist
594 while (taglist[0].ti_Tag != TAG_DONE)
597 switch (taglist[0].ti_Tag)
599 case PTT_TYPE:
600 *((LONG *)taglist[0].ti_Data) = root->table->type;
601 break;
602 case PTT_RESERVED:
603 *((LONG *)taglist[0].ti_Data) =
604 root->de.de_Surfaces*root->de.de_BlocksPerTrack*2; /* 2 cylinders */
605 break;
607 taglist++;
609 return 0;
612 LONG PartitionRDBSetPartitionTableAttrs
614 struct Library *PartitionBase,
615 struct PartitionHandle *root,
616 struct TagItem *taglist
620 while (taglist[0].ti_Tag != TAG_DONE)
623 switch (taglist[0].ti_Tag)
626 taglist++;
628 return 0;
631 LONG PartitionRDBGetPartitionAttrs
633 struct Library *PartitionBase,
634 struct PartitionHandle *ph,
635 struct TagItem *taglist
639 while (taglist[0].ti_Tag != TAG_DONE)
641 struct PartitionBlock *data = (struct PartitionBlock *)ph->data;
643 switch (taglist[0].ti_Tag)
645 case PT_GEOMETRY:
647 struct DriveGeometry *dg = (struct DriveGeometry *)taglist[0].ti_Data;
648 CopyMem(&ph->dg, dg, sizeof(struct DriveGeometry));
650 break;
651 case PT_DOSENVEC:
652 CopyMem(&ph->de, (struct DosEnvec *)taglist[0].ti_Data, sizeof(struct DosEnvec));
653 break;
654 case PT_TYPE:
656 struct PartitionType *ptype=(struct PartitionType *)taglist[0].ti_Data;
657 ULONG dt = AROS_LONG2BE(ph->de.de_DosType);
659 CopyMem(&dt, ptype->id, 4);
660 ptype->id_len = 4;
662 break;
663 case PT_NAME:
664 CopyMem(ph->ln.ln_Name, (UBYTE *)taglist[0].ti_Data, 32);
665 break;
666 case PT_BOOTABLE:
667 *((LONG *)taglist[0].ti_Data) = (AROS_BE2LONG(data->pb_Flags) & PBFF_BOOTABLE) ? TRUE : FALSE;
668 break;
669 case PT_AUTOMOUNT:
670 *((LONG *)taglist[0].ti_Data) = (AROS_BE2LONG(data->pb_Flags) & PBFF_NOMOUNT) ? FALSE : TRUE;
671 break;
673 taglist++;
675 return 0;
678 LONG PartitionRDBSetPartitionAttrs
680 struct Library *PartitionBase,
681 struct PartitionHandle *ph,
682 struct TagItem *taglist
686 while (taglist[0].ti_Tag != TAG_DONE)
688 struct PartitionBlock *data = (struct PartitionBlock *)ph->data;
690 switch (taglist[0].ti_Tag)
692 case PT_DOSENVEC:
694 struct DosEnvec *de = (struct DosEnvec *)taglist[0].ti_Data;
696 CopyMem(de, &ph->de, (de->de_TableSize+1)*sizeof(IPTR));
697 CopyHost2BEDosEnvec((SIPTR *)de, data->pb_Environment, de->de_TableSize+1);
699 break;
700 case PT_TYPE:
702 struct PartitionType *ptype=(struct PartitionType *)taglist[0].ti_Data;
703 ULONG dt;
705 CopyMem(ptype->id, &dt, 4);
706 ph->de.de_DosType = AROS_BE2LONG(dt);
707 data->pb_Environment[DE_DOSTYPE] = dt;
709 break;
710 case PT_NAME:
712 STRPTR name = (STRPTR)taglist[0].ti_Data;
713 ULONG len = strlen(name);
715 CopyMem(name, ph->ln.ln_Name, len+1);
716 CopyMem(name, data->pb_DriveName+1, len);
717 data->pb_DriveName[len+1] = 0;
718 data->pb_DriveName[0] = len;
720 break;
721 case PT_BOOTABLE:
722 if (taglist[0].ti_Data)
723 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) | PBFF_BOOTABLE);
724 else
725 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) & ~PBFF_BOOTABLE);
726 break;
727 case PT_AUTOMOUNT:
728 if (taglist[0].ti_Data)
729 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) & ~PBFF_NOMOUNT);
730 else
731 data->pb_Flags = AROS_LONG2BE(AROS_BE2LONG(data->pb_Flags) | PBFF_NOMOUNT);
732 break;
734 taglist++;
736 return 0;
739 struct PartitionHandle *PartitionRDBAddPartition
741 struct Library *PartitionBase,
742 struct PartitionHandle *root,
743 struct TagItem *taglist
747 if (findTagItem(PT_DOSENVEC, taglist) != NULL)
749 struct PartitionBlock *pblock;
750 struct PartitionHandle *ph;
751 struct PartitionHandle *oph;
753 ph = AllocMem(sizeof(struct PartitionHandle), MEMF_PUBLIC | MEMF_CLEAR);
754 if (ph)
756 ph->ln.ln_Name = AllocVec(32, MEMF_PUBLIC | MEMF_CLEAR);
757 if (ph->ln.ln_Name)
759 pblock = AllocMem(sizeof(struct PartitionBlock), MEMF_PUBLIC | MEMF_CLEAR);
760 if (pblock)
762 ph->root = root;
763 ph->bd = root->bd;
764 ph->data = pblock;
765 pblock->pb_ID = AROS_LONG2BE(IDNAME_PARTITION);
766 pblock->pb_SummedLongs = AROS_LONG2BE(sizeof(struct PartitionBlock)/4);
767 PartitionRDBSetPartitionAttrs(PartitionBase, ph, taglist);
768 oph = (struct PartitionHandle *)root->table->list.lh_Head;
769 while (oph->ln.ln_Succ)
771 if (ph->de.de_LowCyl<oph->de.de_LowCyl)
772 break;
773 oph = (struct PartitionHandle *)oph->ln.ln_Succ;
775 if (oph->ln.ln_Succ)
777 oph = (struct PartitionHandle *)oph->ln.ln_Pred;
778 if (oph->ln.ln_Pred)
780 Insert(&root->table->list, &ph->ln, &oph->ln);
782 else
783 AddHead(&root->table->list, &ph->ln);
785 else
786 AddTail(&root->table->list, &ph->ln);
787 if (findTagItem(PT_DOSENVEC, taglist) == NULL)
789 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
790 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
791 ph->dg.dg_Heads = ph->de.de_Surfaces;
792 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
793 ph->dg.dg_Cylinders = ph->de.de_HighCyl - ph->de.de_LowCyl + 1;
794 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
796 return ph;
798 FreeVec(ph->ln.ln_Name);
800 FreeMem(ph, sizeof(struct PartitionHandle));
803 return NULL;
806 void PartitionRDBDeletePartition
808 struct Library *PartitionBase,
809 struct PartitionHandle *ph
813 PartitionRDBFreeHandle(PartitionBase, ph);
816 struct PartitionAttribute PartitionRDBPartitionTableAttrs[]=
818 {PTTA_TYPE, PLAM_READ},
819 {PTTA_RESERVED, PLAM_READ},
820 {PTTA_DONE, 0}
823 struct PartitionAttribute *PartitionRDBQueryPartitionTableAttrs(struct Library *PartitionBase)
825 return PartitionRDBPartitionTableAttrs;
828 struct PartitionAttribute PartitionRDBPartitionAttrs[]=
830 #warning "TODO: implement write"
831 {PTA_GEOMETRY, PLAM_READ},
832 {PTA_DOSENVEC, PLAM_READ | PLAM_WRITE},
833 {PTA_TYPE, PLAM_READ | PLAM_WRITE},
834 {PTA_NAME, PLAM_READ | PLAM_WRITE},
835 {PTA_BOOTABLE, PLAM_READ | PLAM_WRITE},
836 {PTA_AUTOMOUNT, PLAM_READ | PLAM_WRITE},
837 {PTA_DONE, 0}
840 struct PartitionAttribute *PartitionRDBQueryPartitionAttrs(struct Library *PartitionBase)
842 return PartitionRDBPartitionAttrs;
845 ULONG PartitionRDBDestroyPartitionTable
847 struct Library *PartitionBase,
848 struct PartitionHandle *root
851 struct RDBData *data;
852 UBYTE buffer[root->de.de_SizeBlock << 2];
854 data = root->table->data;
855 CopyMem(&data->rdb, buffer, sizeof(struct RigidDiskBlock));
856 ((struct RigidDiskBlock *)buffer)->rdb_ID = 0;
857 if (writeBlock(PartitionBase, root, data->rdbblock, buffer))
858 return 1;
859 return 0;
862 struct PTFunctionTable PartitionRDB =
864 PHPTT_RDB,
865 "RDB",
866 PartitionRDBCheckPartitionTable,
867 PartitionRDBOpenPartitionTable,
868 PartitionRDBClosePartitionTable,
869 PartitionRDBWritePartitionTable,
870 PartitionRDBCreatePartitionTable,
871 PartitionRDBAddPartition,
872 PartitionRDBDeletePartition,
873 PartitionRDBGetPartitionTableAttrs,
874 PartitionRDBSetPartitionTableAttrs,
875 PartitionRDBGetPartitionAttrs,
876 PartitionRDBSetPartitionAttrs,
877 PartitionRDBQueryPartitionTableAttrs,
878 PartitionRDBQueryPartitionAttrs,
879 PartitionRDBDestroyPartitionTable