2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
7 * -date------ -name------------------- -description-----------------------------
8 * 26-dec-2007 [Tomasz Wiszkowski] added disk validation
9 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
10 * 05-jan-2008 [Tomasz Wiszkowski] removed requester prompting for validation
11 * to allow volume validation during boot-up
22 #include "checksums.h"
24 #include "afsblocks.h"
25 #include "baseredef.h"
26 #include "validator.h"
29 BOOL
mediumPresent(struct IOHandle
*ioh
) {
30 return (ioh
->ioflags
& IOHF_DISK_IN
)==IOHF_DISK_IN
;
33 /*******************************************
35 Descr.: build infos for a new medium
37 Output: 0 for success; error code otherwise
38 ********************************************/
39 LONG
newMedium(struct AFSBase
*afsbase
, struct Volume
*volume
) {
40 struct BlockCache
*blockbuffer
;
42 BOOL gotdostype
= FALSE
;
47 /* Check validity of root block first, since boot block may be left over
48 from an overwritten partition of a different size
49 Read bootblock first to prevent multiple seeks when using floppies
51 blockbuffer
=getBlock(afsbase
, volume
,0);
52 volume
->dostype
= dostype
= 0;
53 volume
->dosflags
= dosflags
= 0;
54 if (blockbuffer
!= NULL
) {
56 dostype
= OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFFFFFF00;
57 dosflags
= OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFF;
60 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
61 if (blockbuffer
== NULL
) {
62 volume
->dostype
= ID_UNREADABLE_DISK
;
65 if (calcChkSum(volume
->SizeBlock
, blockbuffer
->buffer
) != 0 ||
66 OS_BE2LONG(blockbuffer
->buffer
[BLK_PRIMARY_TYPE
]) != T_SHORT
||
67 OS_BE2LONG(blockbuffer
->buffer
[BLK_SECONDARY_TYPE(volume
)]) != ST_ROOT
)
69 D(bug("[afs] newMedium: incorrect checksum or root block type (%ld)\n",
70 OS_BE2LONG(blockbuffer
->buffer
[BLK_SECONDARY_TYPE(volume
)])));
71 volume
->dostype
= ID_NOT_REALLY_DOS
;
72 return ERROR_NOT_A_DOS_DISK
;
75 if (gotdostype
== FALSE
) {
76 volume
->dostype
= ID_UNREADABLE_DISK
;
79 if (dostype
!= 0x444F5300)
81 blockbuffer
= getBlock(afsbase
, volume
, 1);
82 dostype
= OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFFFFFF00;
83 dosflags
= OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFF;
85 if (dostype
!= 0x444F5300)
87 D(bug("[afs] newMedium: incorrect DOS type (0x%lx)\n",
89 volume
->dostype
= ID_NOT_REALLY_DOS
;
90 return ERROR_NOT_A_DOS_DISK
;
92 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
93 if (blockbuffer
== NULL
) {
94 volume
->dostype
= ID_UNREADABLE_DISK
;
98 volume
->dostype
= dostype
;
99 volume
->dosflags
= dosflags
;
103 volume
->bitmapblockpointers
[i
]=OS_BE2LONG
105 blockbuffer
->buffer
[BLK_BITMAP_POINTERS_START(volume
)+i
]
108 volume
->bitmapextensionblock
=OS_BE2LONG
110 blockbuffer
->buffer
[BLK_BITMAP_EXTENSION(volume
)]
112 if (!blockbuffer
->buffer
[BLK_BITMAP_VALID_FLAG(volume
)])
114 /* since our disk is invalid at this point, *
115 * we want to spawn a new process that will *
116 * perform disk validation while we move on */
118 volume
->usedblockscount
=0;
119 volume
->state
= ID_VALIDATING
;
121 launchValidator(afsbase
, volume
);
125 * it's safe to assume that the block is still there
127 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
129 if (blockbuffer
->buffer
[BLK_BITMAP_VALID_FLAG(volume
)])
131 blockbuffer
->flags
|= BCF_USED
; // won't be cleared until volume is ejected
132 volume
->usedblockscount
=countUsedBlocks(afsbase
, volume
);
133 volume
->state
= diskWritable(afsbase
, &volume
->ioh
) ?
134 ID_VALIDATED
: ID_WRITE_PROTECTED
;
136 error
= osMediumInit(afsbase
, volume
, blockbuffer
);
139 /* for free block searching */
140 volume
->lastaccess
=volume
->rootblock
;
144 /*******************************************
146 Descr.: maybe a better name would be mountVolume
147 allocate resources for a new mounted device
148 Input : device - device pointer
149 blockdevice - name of blockdevice
150 unit - unit number of blockdevice
151 devicedef - medium geometry data
152 error - return error code
153 Output: 0 on error (error set dos dos error);
154 pointer to struct Volume on success
155 ********************************************/
156 struct Volume
*initVolume
158 struct AFSBase
*afsbase
,
159 struct Device
*device
,
160 CONST_STRPTR blockdevice
,
163 struct DosEnvec
*devicedef
,
167 struct Volume
*volume
;
169 if (blockdevice
== NULL
) {
170 *error
= ERROR_NO_DISK
;
174 volume
= AllocMem(sizeof(struct Volume
) + strlen(blockdevice
) + 1,MEMF_PUBLIC
| MEMF_CLEAR
);
177 volume
->device
= device
;
178 volume
->ioh
.blockdevice
= (STRPTR
)(&volume
[1]); /* Data after the volume alloc */
179 strcpy(volume
->ioh
.blockdevice
, blockdevice
);
180 volume
->ioh
.unit
= unit
;
181 volume
->ioh
.flags
= flags
;
182 volume
->SizeBlock
= devicedef
->de_SizeBlock
183 * devicedef
->de_SectorPerBlock
;
184 volume
->sectorsize
= devicedef
->de_SizeBlock
<< 2;
185 volume
->blocksectors
= devicedef
->de_SectorPerBlock
;
186 if (devicedef
->de_TableSize
>=20)
187 volume
->bootblocks
=devicedef
->de_BootBlocks
;
189 volume
->bootblocks
=devicedef
->de_Reserved
;
190 volume
->numbuffers
= devicedef
->de_NumBuffers
;
191 volume
->blockcache
=initCache(afsbase
, volume
, volume
->numbuffers
);
192 if (volume
->blockcache
!= NULL
)
194 if (openBlockDevice(afsbase
, &volume
->ioh
)!= NULL
)
196 volume
->countblocks
=
199 devicedef
->de_HighCyl
-devicedef
->de_LowCyl
+1
200 )*devicedef
->de_Surfaces
*devicedef
->de_BlocksPerTrack
202 devicedef
->de_SectorPerBlock
204 volume
->rootblock
=(volume
->countblocks
-1+devicedef
->de_Reserved
)/2;
206 devicedef
->de_LowCyl
*
207 devicedef
->de_Surfaces
*
208 devicedef
->de_BlocksPerTrack
;
211 (devicedef
->de_HighCyl
+1)
212 *devicedef
->de_Surfaces
213 *devicedef
->de_BlocksPerTrack
215 check64BitSupport(afsbase
, volume
);
216 volume
->ah
.volume
=volume
;
217 if (mediumPresent(&volume
->ioh
))
219 *error
= newMedium(afsbase
, volume
);
223 if ((*error
== 0) || (*error
== ERROR_NOT_A_DOS_DISK
))
225 D(bug("[afs] initVolume: BootBlocks=%d\n",volume
->bootblocks
));
226 D(bug("[afs] initVolume: RootBlock=%ld\n",volume
->rootblock
));
227 volume
->ah
.header_block
= volume
->rootblock
;
233 *error
=ERROR_NO_FREE_STORE
;
235 freeCache(afsbase
, volume
->blockcache
);
239 *error
=ERROR_NO_FREE_STORE
;
241 FreeMem(volume
,sizeof(struct Volume
) + strlen(blockdevice
) + 1);
244 *error
=ERROR_NO_FREE_STORE
;
248 /*******************************************
250 Descr.: maybe a better name would be unmountVolume
251 free resources allocated by initVolume
252 Input : volume - volume to unmount
254 ********************************************/
255 void uninitVolume(struct AFSBase
*afsbase
, struct Volume
*volume
) {
257 osMediumFree(afsbase
, volume
, TRUE
);
258 if (volume
->blockcache
!= NULL
)
259 freeCache(afsbase
, volume
->blockcache
);
260 closeBlockDevice(afsbase
, &volume
->ioh
);
261 FreeMem(volume
,sizeof(struct Volume
) + strlen(volume
->ioh
.blockdevice
) + 1);
265 LONG
writeprotectVolume(struct AFSBase
*afsbase
, struct Volume
*volume
, BOOL on
, ULONG key
)
269 if(on
&& (volume
->state
== ID_WRITE_PROTECTED
))
270 { // Already write protected
271 error
= ERROR_DISK_WRITE_PROTECTED
;
272 D(bug("[AFS] Volume: Already write protected (%l)\n", error
));
275 { // Attempt to write protect
279 volume
->state
= ID_WRITE_PROTECTED
; // : ID_VALIDATED;
280 } else { // Without a key
281 volume
->state
= ID_WRITE_PROTECTED
;
283 } else { // Attempt to write enable
286 if(key
== volume
->key
)
288 volume
->state
= ID_VALIDATED
;
290 } else { // Key is incorrect
291 error
= ERROR_INVALID_COMPONENT_NAME
;
292 D(bug("[AFS] Volume: Wrong key (%l)\n", error
));
295 } else { // There is no key
296 volume
->state
= ID_VALIDATED
;
300 /* Return success indicator */
303 /* vim: set noet ts=3 ai fdm=marker fmr={,} :*/