2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
7 #include <proto/exec.h>
8 #include <proto/expansion.h>
9 #include <proto/gadtools.h>
10 #include <proto/intuition.h>
11 #include <proto/partition.h>
13 #include <devices/bootblock.h>
14 #include <devices/scsidisk.h>
15 #include <devices/trackdisk.h>
16 #include <dos/dosextens.h>
17 #include <exec/memory.h>
18 #include <libraries/expansion.h>
19 #include <libraries/partition.h>
24 #include "partitiontables.h"
26 #include "hdtoolbox_support.h"
31 extern struct GUIGadgets gadgets
;
33 void getPartitionInfo(struct PartitionTable
*table
, struct PartitionHandle
*ph
)
35 D(bug("[HDToolBox] getPartitionInfo()\n"));
37 table
->tattrlist
= QueryPartitionTableAttrs(ph
);
38 table
->pattrlist
= QueryPartitionAttrs(ph
);
39 GetPartitionTableAttrsA
42 PTT_TYPE
, &table
->type
,
43 PTT_RESERVED
, &table
->reserved
,
44 PTT_MAX_PARTITIONS
, &table
->max_partitions
,
47 D(bug("[HDToolBox] getPartitionInfo:type=%ld\n", table
->type
));
50 struct PartitionTable
*newPartitionTable(struct PartitionHandle
*ph
)
52 struct PartitionTable
*table
;
54 D(bug("[HDToolBox] newPartitionTable()\n"));
56 table
= AllocMem(sizeof(struct PartitionTable
), MEMF_PUBLIC
| MEMF_CLEAR
);
58 getPartitionInfo(table
, ph
);
62 BOOL
findPartitionTable(struct HDTBPartition
*partition
)
64 D(bug("[HDToolBox] findPartitionTable()\n"));
66 if (OpenPartitionTable(partition
->ph
) == 0)
68 partition
->table
= newPartitionTable(partition
->ph
);
69 if (partition
->table
!= NULL
)
71 ClosePartitionTable(partition
->ph
);
76 void freePartitionTable(struct HDTBPartition
*partition
)
78 D(bug("[HDToolBox] freePartitionTable()\n"));
80 ClosePartitionTable(partition
->ph
);
81 FreeMem(partition
->table
, sizeof(struct PartitionTable
));
84 BOOL
makePartitionTable(struct HDTBPartition
*table
, ULONG type
)
86 D(bug("[HDToolBox] makePartitionTable()\n"));
90 /* if there is already a partition table then free it */
91 freePartitionList(&table
->listnode
.list
);
92 DestroyPartitionTable(table
->ph
);
96 table
->table
= AllocMem(sizeof(struct PartitionTable
), MEMF_PUBLIC
| MEMF_CLEAR
);
100 if (CreatePartitionTable(table
->ph
, type
) == 0)
102 getPartitionInfo(table
->table
, table
->ph
);
109 /**************************************************************************/
112 ULONG
getOffset(struct PartitionHandle
*ph
)
117 D(bug("[HDToolBox] getOffset()\n"));
121 GetPartitionAttrsA(ph
, PT_DOSENVEC
, de
, TAG_DONE
);
122 offset
+= de
.de_LowCyl
;
129 Output: 0 - no mount (no partition change)
130 1 - mount that device
131 2 - reboot not really neccessary
132 (FS not so important things changed like de_Mask)
133 3 - reboot neccessary
134 (FS important things changed like de_LowCyl)
136 WORD
checkMount(struct HDTBPartition
*table
, STRPTR name
, struct DosEnvec
*de
)
140 struct DeviceNode
*entry
;
143 D(bug("[HDToolBox] checkMount('%s')\n", name
));
145 dl
= LockDosList(LDF_READ
| LDF_DEVICES
);
148 entry
= (struct DeviceNode
*)FindDosEntry(dl
, name
, LDF_DEVICES
);
151 struct FileSysStartupMsg
*fssm
;
152 struct DosEnvec
*d_de
;
155 fssm
= (struct FileSysStartupMsg
*)BADDR(entry
->dn_Startup
);
156 devname
= AROS_BSTR_ADDR(fssm
->fssm_Device
);
158 (fssm
->fssm_Unit
!= table
->hd
->unit
) ||
159 (strcmp(devname
, table
->hd
->devname
))
162 retval
= 3; /* better do a reboot */
166 d_de
= (struct DosEnvec
*)BADDR(fssm
->fssm_Environ
);
167 i
= getOffset(table
->ph
);
169 (d_de
->de_SizeBlock
!= de
->de_SizeBlock
) ||
170 (d_de
->de_Reserved
!= de
->de_Reserved
) ||
171 (d_de
->de_PreAlloc
!= de
->de_PreAlloc
) ||
172 (d_de
->de_LowCyl
!= (de
->de_LowCyl
+i
)) ||
173 (d_de
->de_HighCyl
!= (de
->de_HighCyl
+i
)) ||
174 (d_de
->de_DosType
!= de
->de_DosType
) ||
177 /* at least one has de_BootBocks */
178 (d_de
->de_TableSize
>=DE_BOOTBLOCKS
) ||
179 (de
->de_TableSize
>=DE_BOOTBLOCKS
)
182 /* if one has no de_BootBlock assume de_BootBlock change */
183 (d_de
->de_TableSize
<DE_BOOTBLOCKS
) ||
184 (de
->de_TableSize
<DE_BOOTBLOCKS
)
188 /* both have de_BootBlocks */
189 (d_de
->de_TableSize
>=DE_BOOTBLOCKS
) &&
190 (de
->de_TableSize
>=DE_BOOTBLOCKS
) &&
191 (d_de
->de_BootBlocks
!= de
->de_BootBlocks
)
199 (d_de
->de_NumBuffers
!= de
->de_NumBuffers
) ||
200 (d_de
->de_BufMemType
!= de
->de_BufMemType
) ||
201 (d_de
->de_MaxTransfer
!= de
->de_MaxTransfer
) ||
202 (d_de
->de_Mask
!= de
->de_Mask
) ||
203 (d_de
->de_BootPri
!= de
->de_BootPri
)
212 UnLockDosList(LDF_READ
| LDF_DEVICES
);
217 void mount(struct HDTBPartition
*table
, struct PartitionHandle
*ph
, STRPTR name
, struct DosEnvec
*de
)
219 struct ExpansionBase
*ExpansionBase
;
220 struct DeviceNode
*dn
;
221 struct DosEnvec
*nde
;
225 D(bug("[HDToolBox] mount('%s')\n", name
));
227 #error "TODO: pass DOS device name in params[0] and set handler name manually"
228 #warning "TODO: get filesystem"
229 if ((de
->de_DosType
& 0xFFFFFF00) == BBNAME_DOS
)
231 ExpansionBase
= (struct ExpansionBase
*)OpenLibrary("expansion.library",41);
234 params
= (IPTR
*)AllocVec(sizeof(struct DosEnvec
)+sizeof(IPTR
)*4, MEMF_PUBLIC
| MEMF_CLEAR
);
237 nde
= (struct DosEnvec
*)¶ms
[4];
238 CopyMem(de
, nde
, sizeof(struct DosEnvec
));
239 params
[0] = (IPTR
)"afs.handler";
240 params
[1] = (IPTR
)table
->hd
->devname
;
241 params
[2] = (IPTR
)table
->hd
->unit
;
243 i
= getOffset(ph
->root
);
245 nde
->de_HighCyl
+= i
;
246 dn
= MakeDosNode(params
);
249 dn
->dn_Name
= MKBADDR(AllocVec(AROS_BSTR_MEMSIZE4LEN(strlen(name
)), MEMF_PUBLIC
));
250 dn
->dn_Ext
.dn_AROS
.dn_DevName
= AROS_BSTR_ADDR(dn
->dn_Name
);
255 AROS_BSTR_putchar(dn
->dn_Name
, i
, name
[i
]);
257 AROS_BSTR_setstrlen(dn
->dn_Name
, i
-1);
258 AddDosNode(nde
->de_BootPri
, ADNF_STARTPROC
, dn
);
263 CloseLibrary((struct Library
*)ExpansionBase
);
267 kprintf("ignored %s: unknown FS (0x%lx)\n", name
, de
->de_DosType
);
270 void mountPartitions(struct List
*ptlist
)
272 struct EasyStruct es
=
274 sizeof(struct EasyStruct
), 0,
279 struct PartitionTableNode
*table
;
280 struct PartitionHandle
*ph
;
284 D(bug("[HDToolBox] mountPartitions()\n"));
286 table
= (struct PartitionTableNode
*)ptlist
->lh_Head
;
287 while (table
->ln
.ln_Succ
)
289 if (table
->type
!= PHPTT_UNKNOWN
)
291 ph
= (struct PartitionHandle
*)table
->ph
->table
->list
.lh_Head
;
292 while (ph
->ln
.ln_Succ
)
294 if (existsAttr(table
->pattrlist
, PTA_AUTOMOUNT
))
298 GetPartitionAttrsA(ph
, PT_AUTOMOUNT
, &flag
, TAG_DONE
);
301 if (existsAttr(table
->pattrlist
, PTA_NAME
))
306 GetPartitionAttrsA(ph
, PT_NAME
, name
, PT_DOSENVEC
, &de
, TAG_DONE
);
307 cm
= checkMount(table
, name
, &de
);
309 mount(table
, ph
, name
, &de
);
311 kprintf("may reboot\n");
313 kprintf("have to reboot\n");
315 kprintf("mount %s not needed\n", name
);
320 kprintf("Partition with no name is automountable\n");
323 ph
= (struct PartitionHandle
*)ph
->ln
.ln_Succ
;
326 table
= (struct PartitionTableNode
*)table
->ln
.ln_Succ
;
333 "A reboot is not necessary because the changes do not\n"
334 "affect the work of any running filesystem.\n"
335 "Do you want to reboot anyway?";
340 "A reboot is required because the changes affect\n"
341 "the work of at least one running filesystem.\n"
342 "Do you want to reboot now?";
344 if (EasyRequestArgs(0, &es
, 0, 0))